P1219 [USACO1.5]八皇后 Checker Challenge
一道很经典的搜索回溯题
思路
考虑到每一行只能够放一个,并且所有行的皇后都不放在同一列上,还要考虑皇后不在同一斜线上
(图片来自互联网,侵删)
用三个数组表示各行,各斜线是否被占,用x+y和x-y+15表示不同方向斜线上的被占的情况,(x-y应考虑负值)
若被占领,则进行回溯。
代码实现
#include <cstdio>
using namespace std;
const int maxn = 101;
int n, sum = 0, ans[maxn] = {};
int check1[maxn] = {},check2[maxn] = {},check3[maxn] = {};
/* check[][0] check[][1] check[][2] 分别用来记录y,x+y,x-y+15是否被占用*/
void print() {
for (int i = 1; i <= n; ++i) {
printf("%d ", ans[i]);
}
printf("\n");
return ;
}
void dfs(int line) {
if(line > n) {
//如果行数超过矩阵大小,则方案成立,总方案数+1
sum++;
if (sum <= 3) //将前三种方案输出
print();
return ;
}
for (int i = 1; i <= n; ++i) {
if(check1[i] == 0 && check2[line + i] == 0 && check3[line - i + 15] == 0) {
ans[line] = i;
check1[i] = 1; check2[line + i] = 1; check3[line - i + 15] = 1;
dfs(line + 1);
check1[i] = 0; check2[line + i] = 0; check3[line - i + 15] = 0;
}
}
}
int main() {
scanf("%d", &n);
dfs(1);//从第一行开始枚举
printf("%d", sum);//输出总方案数
return 0;
}