Solution
Analysis
很经典的8皇后问题, 题目中已给出了几个皇后的位置并且不允许更改这几个皇后的位置
要求的输出是8*8的棋盘
可以使用递归的思路来求解
Design
使用了1个int数组来存储每行皇后的位置
使用了3个bool数组来判断当前列, 主对角线, 副对角线是否有冲突
设计求解函数
使用栈来存储中间的数据,(例如正在处理第3行, 然后放置到了第4列, 之后要去第4行放置皇后, 此时需要将第三行的行号, 以及处理到了哪个位置先存储起来)
处理的过程中, 如果遇到了不能更改的行, 则直接去下一行, 如果全部行都处理完成了, 那么就可以输出然后结束程序.
至于普通的情况, 先判断之前是不是放置过了皇后, 如果是的话, 将皇后先拿起(还需要修改列, 主对角线, 副对角线冲突的数组), 找到了位置, 将皇后放进去(继续修改列, 主对角线, 副对角线冲突的数组), 然后处理下一行
Code
#include <bits/stdc++.h>
using namespace std;
int queen_in_rows[8];
bool col_free[8], upward_free[15], downward_free[15];
bool can_change[8];
void print_board() {
int i, j;
for (i = 0; i < 8; i++) {
for (j = 0; j < queen_in_rows[i]; j++)
printf(".");
printf("Q");
for (j = queen_in_rows[i] + 1; j < 8; j++)
printf(".");
printf("
");
}
}
void solution() {
stack<pair<int, int> > S;
pair<int, int> P;
int row, col;
S.push(make_pair(0, 0));
while (1) {
P = S.top(); S.pop();
row = P.first;
col = P.second;
// 如果全部处理完了, 退出
if (row == 8) break;
// 如果当前行输入中已给出, 直接处理下一行
if (!can_change[row]) {
// cout << "can't change line " << row << endl;
S.push(make_pair(row + 1, 0));
continue;
}
// 如果该行之前放置过皇后, 那么将该皇后拿起, 然后查找位置从下一列开始
if (queen_in_rows[row] != -1) {
queen_in_rows[row] = -1;
col_free[col] = true;
upward_free[row + col] = true;
downward_free[row - col + 7] = true;
col++;
}
// 尝试寻找可以放置皇后的位置
while (col < 8) {
if (col_free[col] && upward_free[row + col]
&& downward_free[row - col + 7])
break;
col++;
}
// 如果没有找到, 则返回上一行处理
if (col == 8)
continue;
// 如果找到了, 则将皇后放入
// cout << "line " << row << " put queen in " << col << endl;
queen_in_rows[row] = col;
col_free[col] = false;
upward_free[row + col] = false;
downward_free[row - col + 7] = false;
// 保存当前行的信息, 然后查找下一行
S.push(make_pair(row, col));
S.push(make_pair(row + 1, 0));
}
while (!S.empty())
S.pop();
print_board();
}
int main(void) {
int i, k, row, col;
for (i = 0; i < 8; i++) {
queen_in_rows[i] = -1;
col_free[i] = true;
upward_free[i] = true;
downward_free[i] = true;
can_change[i] = true;
}
for (i = 8; i < 15; i++) {
upward_free[i] = true;
downward_free[i] = true;
}
scanf("%d", &k);
while (k--) {
scanf("%d %d", &row, &col);
queen_in_rows[row] = col;
can_change[row] = false;
col_free[col] = false;
upward_free[row + col] = false;
downward_free[row - col + 7] = false;
}
solution();
}