| Time Limit: 1000MS | Memory Limit: 131072K | |||
| Total Submissions: 3469 | Accepted: 1275 | Special Judge | ||
Description
The eight queens puzzle is the problem of putting eight chess queens on an 8 × 8 chessboard such that none of them is able to capture any other. The puzzle has been generalized to arbitrary n × n boards. Given n, you are to find a solution to the n queens puzzle.
Input
The input contains multiple test cases. Each test case consists of a single integer n between 8 and 300 (inclusive). A zero indicates the end of input.
Output
For each test case, output your solution on one line. The solution is a permutation of {1, 2, …, n}. The number in the ith place means the ith-column queen in placed in the row with that number.
Sample Input
8 0
Sample Output
5 3 1 6 8 2 4 7
Source
N皇后问题,主要是为了测试代码:
#include <iostream>
#include <vector>
using namespace std;
class Queen {
public:
char QChar, BChar; // 代表皇后和空白的字符
int * q_in_row; // q_in_row[i] = j表示在第i行第j列有个皇后
bool * col_free; // col_free[i] = true表示第i列没有皇后
bool * up_free; // 从右上到左下的对角线是否可以放置皇后
bool * down_free; // 从左上到右下的对角线是否可以放置皇后
int N; // 皇后个数、正方形棋盘的边长
bool ONE, NUM, ALL; // 由于只有一个递归函数,三个变量用于区分是哪一个问题
bool ONE_FINISH; // 判断只返回一个解的问题是否已经解决
int num; // 所有解的个数
vector<vector<char> > oneAns; // 一个解
vector<vector<vector<char> > > allAns; // 所有解
Queen() {
QChar = 'Q';
BChar = '.';
ONE = NUM = ALL = ONE_FINISH = false;
}
void changeChar(char q, char b) { // 可以改变代表皇后和空白的字符
QChar = q;
BChar = b;
}
void makeBoard(int n) {
N = n;
q_in_row = new int[N];
col_free = new bool[N];
up_free = new bool[2 * N - 1];
down_free = new bool[2 * N - 1];
for (int i = 0; i < N; i++) q_in_row[i] = col_free[i] = true;
for (int i = 0; i < 2 * N - 1; i++) up_free[i] = down_free[i] = true;
}
void deleteBoard() {
delete []q_in_row;
delete []col_free;
delete []up_free;
delete []down_free;
}
void construct_solution() {
int row = 0;
if (N % 6 != 2 && N % 6 != 3) {
if (N % 2 == 0) {
for (int i = 2; i <= N; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
} else {
for (int i = 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N; i += 2) q_in_row[row++] = i - 1;
}
} else {
if (N % 2 == 0) {
if ((N / 2) % 2 == 0) {
for (int i = N / 2; i <= N; i += 2) q_in_row[row++] = i - 1;
for (int i = 2; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = N / 2 + 3; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;
} else {
for (int i = N / 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = N / 2 + 3; i <= N; i += 2) q_in_row[row++] = i - 1;
for (int i = 2; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;
}
} else {
if ((N / 2) % 2 == 0) {
for (int i = N / 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
for (int i = 2; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = N / 2 + 3; i <= N - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;
q_in_row[row++] = N - 1;
} else {
for (int i = N / 2; i <= N - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = 1; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;
for (int i = N / 2 + 3; i <= N - 1; i += 2) q_in_row[row++] = i - 1;
for (int i = 2; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;
q_in_row[row++] = N - 1;
}
}
}
write_in(oneAns);
}
vector<vector<char> > Return_an_ans(int n) {
makeBoard(n);
if (n > 3) {
construct_solution();
deleteBoard();
return oneAns;
}
ONE = true;
dfs(0);
deleteBoard();
return oneAns;
}
int Return_all_ans_num(int n) {
makeBoard(n);
NUM = true;
num = 0;
dfs(0);
deleteBoard();
return num;
}
vector<vector<vector<char> > > Return_all_ans(int n) {
makeBoard(n);
ALL = true;
dfs(0);
deleteBoard();
return allAns;
}
void write_in(vector<vector<char> > & a) {
a.resize(N);
for (int i = 0; i < N; i++) {
a[i].resize(N);
for (int j = 0; j < N; j++) {
if (q_in_row[i] == j) a[i][j] = QChar;
else a[i][j] = BChar;
}
}
}
void dfs(int now) {
if (now == N) {
if (ONE) {
ONE_FINISH = true;
write_in(oneAns);
return;
}
if (NUM) {
num++;
return;
}
if (ALL) {
vector<vector<char> > a;
write_in(a);
allAns.push_back(a);
return;
}
}
for (int col = 0; col < N; col++) {
if (col_free[col] && up_free[now + col] && down_free[now - col + N - 1]) {
q_in_row[now] = col;
col_free[col] = up_free[now + col] = down_free[now - col + N - 1] = false;
dfs(now + 1);
if (ONE && ONE_FINISH) return;
col_free[col] = up_free[now + col] = down_free[now - col + N - 1] = true;
}
}
}
};
int main() {
std::cout.sync_with_stdio(false);
while (1) {
Queen q;
int n;
cin >> n;
if (n == 0) break;
vector<vector<char> > ans = q.Return_an_ans(n);
for (int i = 0; i < ans.size(); i++) {
for (int j = 0; j < ans[i].size(); j++) {
if (ans[i][j] == 'Q') {
if (i) cout << " ";
cout << j + 1;
}
}
}
cout << endl;
}
return 0;
}
本文介绍了一种解决N皇后问题的有效算法。通过递归搜索和冲突检查,文章提供了一个能够找到任意大小N×N棋盘上皇后放置方案的C++程序实现。特别地,对于N大于3的情况,给出了一个预设的解决方案。
685

被折叠的 条评论
为什么被折叠?



