Grade 11 · BacktrackingCitește în română
The n-queens problem
Original: Problema celor n dame
The idea
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.
Original description (Romanian)
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.
- Complexity
- exponential; far below n^n thanks to the continuation conditions
- Grade
- Grade 11 (Clasa a XI-a)
- Chapter
- Backtracking
Examples
Input
4
Expected output
2 4 1 3 3 1 4 2 Total: 2
Input
3
Expected output
Total: 0
The code
Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.
/*
* 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;
}
Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.