题解 P1219 【八皇后】
这道题其实我还没学回溯就写了,大概思路就是:
搜索,二进制优化。
先附上代码
#include<bits/stdc++.h>
using namespace std;//用位运算优化
int n,mans,p;
int mark[100],bin[1<<20];
void dfs(int x/*行*/,int a,int b,int c){//列,左上角,右上角标记
if(x>n){
ans++;
if(ans>=1&&ans<=3){
for(int i=1;i<=n;i++)printf("%d ",mark[i]+1);//输出标记了的列
puts("");
}
return;
}
int t=(a|b|c)^p;//p记录棋盘下标范围,t判断是否在棋盘内
while(t) {
int i=t&(-t);//二进制找到最后一个的全值
mark[x]=bin[i];//选择当前棋子
dfs(x+1,a|i,(b|i)>>1,((c|i)<<1)&p);//对当前棋子做标记,继续查找
//a|i记录当前列不能走,b|i表示左上角,(c|i)<<1)&p查找右上角与当前列的重合
t-=i;
}
}
int main(){
scanf("%d",&n);
p=(1<<n)-1;//用二进制表示下标范围;
bin[0]=1;
for(int i=1; i<=n; i++)bin[1<<i]=i;//二进制标记归位
dfs(1,0,0,0);
printf("%d",ans);
return 0;
}
不难看出,代码中用了二进制表示坐标,因为位运算比一般的运算要快很多,所以过程也是比较快的!
第一次写题解,希望采纳,谢谢!