洛谷p1219搜索问题p1219
思路:1.用行数组存储结果。2.无法搜索就回溯,取消标记 3.边界条件是到达最大深度的下一个深度,此时可能已经找到了解
4.将对角线之和为定值或者之差为定值来对每一条对角线进行标记。
#include<stdio.h>
int cnt=1;
int ls[105],rs[105],lie[15],ans[15];//ans[i]代表第i行第ans[i]里面有棋子
int n;
void put(){
int i;
if(cnt<=3){
for(i=1;i<=n;i++)
printf("%d ",ans[i]);
printf("\n");
}
cnt++;
}
//第k行
void dfs(int k){
if(k>n)
{
put();
return;
}
int i;
for(i=1;i<=n;i++)
{
if(!ls[i+k] && !rs[i-k+n] && !lie[i]){ //没有标记才进行搜索
ans[k]=i;
lie[i]=1;
ls[k+i]=1;
rs[i-k+n]=1;//标记
dfs(k+1);
lie[i]=0;
ls[k+i]=0;
rs[i-k+n]=0; //回溯
}
}
return;
}
int main(){
scanf("%d",&n);
dfs(1);
printf("%d",cnt-1);
}
直接进行标记运用两重循环来进行:
for(int i=0;i<n;i++)
{
int ok=1;
c[queen]=i;//把此行皇后放在i列
for(int j=0;j<queen;j++)
if(c[queen]==c[j]||queen-c[queen]==j-c[j]||queen+c[queen]==j+c[j])//检查是否冲突
{ok=0;break;}
if(ok) dsf(queen+1);//如果合法就继续
}