P1219 [USACO1.5] 八皇后 Checker Challenge题解
这题我本来是不想写题解的,但由于这题很经典且我做了3遍都能不理解,我为我自己大家写下了这篇回忆录题解。
回归主题
妥妥又经典的 这是一句病句别学我,从1枚举棋子列数,记录下棋子所在列,两个对角线,下一次如果行与两个斜对角没有可以攻击到这个点的棋子,那么就把棋子放进去。
思路已经明确。那么怎么记录下棋子所在的列与对角线捏(本人第二次就栽在这)?
列:
我们可以开个循环,直接记录循环到了哪一列(so easy)。
对角线:
列非常容易记录,但对角线就麻烦了,这里引用一张别人的图片。
我们可以很清楚滴看到,当
然鹅,本人第三次还是不会
当我查看我之前的代码时(代码详见下面的
很明显,这个人没学好回溯。。。
如果你的回溯很ok就可以跳过这里啦。
当
这样,代码就大功告成了。
ac code:
#include<bits/stdc++.h>
using namespace std;
int sum,n,a[20],d1[20],d2[80],d3[80];//d1记录列,d2和d3记录对角线
void dfs(int x){
if(x>n){//如果已经放入n个棋子
sum++;//放置总数+1
if(sum<=3){//如果是前三个
for(int i=1;i<=n;i++)//输出
cout<<a[i]<<' ';
cout<<endl;
}
}
for(int i=1;i<=n;i++){
if(d1[i]==0&&d2[i+x]==0&&d3[x-i+15]==0){//没有棋子可以攻击到这里
a[x]=i;//记录x行的棋子在i列
d1[i]=1;d2[i+x]=1;d3[x-i+15]=1;//标记
dfs(x+1);
d1[i]=0;d2[i+x]=0;d3[x-i+15]=0;//回溯
}
}
}
int main(){
cin>>n;
dfs(1);
cout<<sum;
return 0;
}
希望大家喜欢反正我喜欢