👤

Mă puteți ajuta va rog la aceasta problema de backtracking? Dacă ați putea sa îmi și explicați algoritmul ar fi super . Mulțumesc anticipat!


Cerința
Se dă un număr natural par n. Determinaţi, în ordine lexicografică, toate modalităţile de a-l scrie pe n ca sumă de puteri ale lui 2 scrise în ordine crescătare. Se vor folosi doar puterile mai mari sau egale cu 2.

Date de intrare
Fișierul de intrare descp2.in conține pe prima linie numărul n.

Date de ieșire
Fişierul de ieşire descp2.out va conţine pe pe fiecare linie câte un şir de numerecare sunt puteri ale lui 2, ordonate crescător, separate prin câte un spaţiu. Suma numerelor din fiecare şir este n. Şirurile vor fi afişate în ordine lexicografică.

Restricții și precizări
2 ≤ n ≤ 250 și este număr par

Exemplu
descp2.in

12
descp2.out

2 2 2 2 2 2
2 2 2 2 4
2 2 4 4
2 2 8
4 4 4
4 8


Răspuns :

[-] Cod C++ explicat :

#include <iostream>

#include <fstream>  

using namespace std;

//Declarare vector, deschidere fisier

int v[100];

ofstream fout("descp2.out");

//Scrie vectorul solutie in fisier

void afisare_solutie(int level) {

for (int index = 1; index < level; index++)

 fout << v[index] << " ";

fout << endl;

}

//Functie pentru backtracking

void bkt(int target_sum, int level) {

//Daca am trecut peste suma target atunci opreste executarea functiei

if (target_sum < 0) return;

//Daca am ajuns la suma target atunci afiseaza

if (target_sum == 0) afisare_solutie(level);

//Pe fiecare pozitie construieste un element putere a lui doi mai mare sau egal decat valoarea elementului anterior

for (v[level] = v[level-1]; v[level] <= target_sum; v[level]*=2) {

 //Apeleaza functia backtracking. Noua suma la care trebuie sa ajungem acum este egala cu suma anterioara minus valoarea elementului generat curent

 bkt(target_sum-v[level], level+1);

}

}

int main() {

int target;

//Citeste numarul la care trebuie sa ajungem din fisier

ifstream fin("descp2.in");

fin >> target;

fin.close();

//Elementul de pe pozitia 0 din vector este initializat cu 2 (deoarece la fiecare pas noul element trebuie sa fie mai mare sau egal decat elementul generat aterior trebuie sa ne asiguram ca exista un astfel de element pentru prima iteratie a programului)

v[0] = 2;

//Apeleaza functia pentru backtracking, incepe generarea elementelor de pe pozitia 1 din vector. Suma la care trebuie sa ajungem initial este cea citita din fisier

bkt(target,1);

//Inchidere fisier

fout.close();

}

[-] Observatie

1. Nu e recomandata folosirea variabilelor globale. Am folosit aici pentru a pastra simplitate si eleganta in parametrii subprogramelor fara a complica programul cu structuri de date complexe.

2. Programul functioneaza pe setul de date pus in exemplu (vezi imagine) dar nu am putut gasi problema pe pbinfo pentru a verifica punctajul.

Vezi imaginea ANDREI750238