O problemă simplă de backtracking de pe#pbinfo asemănătoare cu Paranteze. Link
Cerința
Se citesc două numere naturale
nșim. Afișați în ordine lexicografică toate cuvintele care sunt formate dinnlitereEșimlitereMcu proprietatea că nu există mai mult de două litereMalăturate și nici mai mult de două litereEalăturate.
Explicație
Practic, condițiile ca să punem o literă pe o poziție sunt următoarele:
- Numărul de litere folosite deja este mai mic decât numărul de litere cerut (
nre<nrespectivnrm<m)- Dacă suntem pe pozițiile 1 și 2 nu mai trebuie să verificăm literele anterioare
- Altfel, dacă ultimele 2 litere sunt diferite putem să punem și
EșiM - Dacă ultimele două litere sunt identice trebuie să punem cealaltă literă
- Dacă nu există posibilitatea de a pune literele în acest fel, programul nu va mai intra în condițiile logice, nu se va mai autoapela funcția și
existarămânefalse, se va afișaIMPOSIBIL
Soluția:
#include <iostream>
using namespace std;
int n, m;
char s[29];
bool exista = 0;
void generare(int nre, int nrm, int pas) {
if (pas == n + m + 1) {
exista = 1;
cout << s + 1 << endl;
} else {
if (nre<n&&(pas <= 2 || s[pas - 1] != s[pas - 2] ||
(s[pas - 1] == s[pas - 2] && s[pas - 1] != 'E'))) {
s[pas] = 'E';
generare(nre + 1, nrm, pas + 1);
}
if (nrm<m&&(pas <= 2 || s[pas - 1] != s[pas - 2] ||
(s[pas - 1] == s[pas - 2] && s[pas - 1] != 'M'))) {
s[pas] = 'M';
generare(nre, nrm + 1, pas + 1);
}
}
}
int main() {
cin >> n >> m;
generare(0, 0, 1);
if (!exista)
cout << "IMPOSIBIL";
}Varianta din curs:
- Ține cont de literele rămase în apelarea funcției prin
cntEșicntD - Folosește vectorul
x[]pentru a stoca răspunsul “codat”, în cifrele 0 și 1 - La afișare folosește ternary expression pentru a decide dacă afișează
EsauMpentru valoarea respectivă - Condițiile sunt un pic diferit exprimate, dar reformulate
