Clasa a XI-a · Metoda backtrackingRead in English
Problema celor n dame în C++
În engleză: The n-queens problem
Ideea
Așezăm n dame pe o tablă n × n astfel încât să nu se atace (nicio pereche pe aceeași linie, coloană sau diagonală). Punem câte o damă pe fiecare linie, iar x[k] este coloana damei de pe linia k. Dama k e validă dacă pentru orice linie i < k: x[i] ≠ x[k] (altă coloană) și |x[i] - x[k]| ≠ k - i (altă diagonală). Se afișează toate soluțiile și numărul lor.
Descrierea în engleză
We place n queens on an n × n board so that none attacks another (no pair on the same row, column or diagonal). We put one queen on every row, and x[k] is the column of the queen on row k. Queen k is valid if for every row i < k: x[i] ≠ x[k] (a different column) and |x[i] - x[k]| ≠ k - i (a different diagonal). All solutions and their number are printed.
- Complexitate
- exponențială; mult sub n^n datorită condițiilor de continuare
- Clasa
- Clasa a XI-a (Grade 11)
- Capitol
- Metoda backtracking
Exemple
Intrare
4
Ieșire așteptată
2 4 1 3 3 1 4 2 Total: 2
Intrare
3
Ieșire așteptată
Total: 0
Codul C++
Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.
/*
* Titlu: Problema celor n dame
* Clasa: 11
* Capitol: Metoda backtracking
* Descriere: Așezăm n dame pe o tablă n × n astfel încât să nu se atace (nicio pereche
* pe aceeași linie, coloană sau diagonală). Punem câte o damă pe fiecare linie,
* iar x[k] este coloana damei de pe linia k. Dama k e validă dacă pentru orice
* linie i < k: x[i] ≠ x[k] (altă coloană) și |x[i] - x[k]| ≠ k - i (altă
* diagonală). Se afișează toate soluțiile și numărul lor.
* Complexitate: exponențială; mult sub n^n datorită condițiilor de continuare
*
* Exemplu
* Intrare: 4
* Ieșire:
* 2 4 1 3
* 3 1 4 2
* Total: 2
*
* Exemplu
* Intrare: 3
* Ieșire: Total: 0
*/
#include <iostream>
using namespace std;
int n, x[20], total = 0;
bool valid(int k)
{
for (int i = 1; i < k; i++)
{
int dif = x[i] - x[k];
if (dif < 0)
{
dif = -dif;
}
if (dif == 0 || dif == k - i)
{
return false;
}
}
return true;
}
void back(int k)
{
for (int c = 1; c <= n; c++)
{
x[k] = c;
if (valid(k))
{
if (k == n)
{
total++;
for (int i = 1; i <= n; i++)
{
cout << x[i] << ' ';
}
cout << '\n';
}
else
{
back(k + 1);
}
}
}
}
int main()
{
cin >> n;
back(1);
cout << "Total: " << total << '\n';
return 0;
}
Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.