Pagini recente » Cod sursa (job #2358444) | Cod sursa (job #568930) | Cod sursa (job #809487) | Cod sursa (job #2331670) | Cod sursa (job #2591249)
/*Sursa clean
Rezumat:
Generez cu backtracking toate posibilitatile de a face flip la linii.
Salvez si actualizez sumele pe coloane intr-un array separat.
In calculul sumei totale adun pt fiecare coloana suma mai mare
dintre flip coloana vs. no-flip coloana, adica abs(suma coloana)
Observatii:
1. In rezultatul final nu conteaza ordinea in care sunt aplicate flip-urile.
2. Doua flip-uri la aceeasi linie sau coloana se anuleaza reciproc.
*/
#include <fstream>
int nrLinii, nrColoane, m[16][16], sumeColoana[16], maxSum = INT_MIN;
void flip(int row) {
for (int j = 0; j < nrColoane; j++) {
m[row][j] *= -1;
sumeColoana[j] += m[row][j]; // pt. a anula termenul vechi
sumeColoana[j] += m[row][j]; // pt. a aplica termenul nou
}
}
int matrixSum() {
int sum = 0;
for (int i = 0; i < nrLinii; i++) {
sum += abs(sumeColoana[i]);
}
return sum;
}
void backtrack(int row) {
if (row == nrLinii) {
int sum = matrixSum();
if (sum > maxSum) maxSum = sum;
}
else {
backtrack(row + 1); // no flip + avansare linie urmatoare
flip(row);
backtrack(row + 1); // flip + avansare linie urmatoare
flip(row); // trebuie facut flip din nou
// dupa revenire, pt. a aduce linia
// la starea dinaintea apelului recursiv
}
}
int main() {
std::ifstream fin("flip.in");
std::ofstream fout("flip.out");
fin >> nrLinii; fin >> nrColoane;
for (int i = 0; i < nrLinii; i++) {
for (int j = 0; j < nrColoane; j++) {
fin >> m[i][j];
sumeColoana[j] += m[i][j];
}
}
fin.close();
backtrack(0);
fout << maxSum;
fout.close();
return 0;
}