P1219 [USACO1.5]八皇后 Checker Challenge
题目:
思路:使用dfs全排列
使用dfs进行遍历全部的方案,根据题目可知,边界条件设置为拿到行数等于n时,输出前三个方案并记录方案数,放置棋子数组使用二维数组存储,记录放下棋子时把整行,整列与对角线全部++,这里++的原因是回溯时如只赋为一的话,有可能会把前面选取的棋子覆盖的整行,整列与对角线的记录给回溯掉。
代码:
#include <bits/stdc++.h>
using namespace std;
int b[1005][1005]= {0}; //放置棋子数组
vector<int> v; //记录方案
int ans=0,n;
void dfs(int s) {
if(s==n+1) { //到达最后一行之后
if(ans<3){
for(auto g:v)
cout << g<< " ";
cout << endl;
}
ans++;
return ;
}
for(int i=1; i<=n; i++) {
if(b[s][i])continue; //是否有棋子
v.push_back(i);
for(int j=1; j<=n; j++) {
b[s][j]++; //整行,整列与对角线
b[j][i]++;//整列
if(s+j<=n&&i+j<=n) b[s+j][i+j]++; //右下对角线
//上方对角线不用的原因是因为每一层下来肯定是上面已经放下棋子了,
//那么上方一定是满的
if(s+j<=n&&i-j>0)b[s+j][i-j]++;//左下对角线
}
dfs(s+1);
for(int j=1; j<=n; j++) { //回溯
b[s][j]--;
b[j][i]--;
if(s+j<=n&&i+j<=n) b[s+j][i+j]--;
if(s+j<=n&&i-j>0)b[s+j][i-j]--;
}
v.pop_back();
}
return;
}
int main() {
cin >> n;
dfs(1);
cout << ans;
return 0;
}