#include #include #define MAX_N 14 FILE *f; int n, numSol; unsigned sol[MAX_N]; // vectorul soluție // bitset de ocupare a coloanelor și diagonalelor // dacă bitul x din col este 1, atunci coloana x este liberă // dacă bitul x din diag este 1, atunci diagonala c - l + n - 1 = x este liberă // dacă bitul x din anti este 1, atunci antidiagonala l + c = x este liberă unsigned col, anti, diag; // Calculează logaritmul în baza 2. Presupune că x este putere a lui 2. int log(unsigned x) { int r = 0; while (x > 1) { x >>= 1; r++; } return r; } void backtrack(int l) { if (l == n) { if (++numSol <= 3) { for (int i = 0; i < n; i++) { fprintf(f, "%d ", 1 + log(sol[i])); } fprintf(f, "\n"); } } else { // Shiftăm și facem AND pe cele trei măști pentru a obține masca pătratelor // de pe linia l pe care putem amplasa o damă. unsigned mask = col & (anti >> l) & (diag >> (n - 1 - l)); // Iterăm doar prin biții setați while (mask) { int lsb = mask & (-(signed)mask); // lsb este 1 << indexul_coloanei_libere sol[l] = lsb; col ^= lsb; anti ^= lsb << l; diag ^= lsb << (n - 1 - l); backtrack(l + 1); col ^= lsb; anti ^= lsb << l; diag ^= lsb << (n - 1 - l); mask ^= lsb; } } } int main(void) { f = fopen("regine.in", "r"); assert(fscanf(f, "%d", &n) == 1); fclose(f); col = (1 << n) - 1; anti = diag = (1 << (2 * n - 1)) - 1; f = fopen("regine.out", "w"); backtrack(0); fprintf(f, "%d\n", numSol); fclose(f); }