题目
N皇后问题(N<=10)
思路来源
蓝书
题解
回溯法,大概入门了
就是枚举每个当前可行状态
然后check当前状态和之前的状态是否冲突
如果冲突就不递归下一层,相当于在搜索树里剪枝剪掉了
否则就搜下一层
预处理打表,不然必然会T
另外考虑一个二维平面,
y-x相同,不妨y=x+k,两点在y=x+k上说明副对角线相同
y+x相同,亦有y+x=b,y=-x+b主对角线相同
都是要剪掉的类型
这里我们按行增序枚举,所以只可能出现列的冲突
精简干练的短代码题要优先掌握啊不然怎么提升码力
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int x,y;
}step[11];
int n,ans[11];
bool vis[11];
void dfs(int pos,int num)
{
if(pos==num)
{
ans[num]++;
return;
}
for(int i=1;i<=num;++i)
{
if(vis[i])continue;
step[pos].x=1+pos;step[pos].y=i;
bool flag=1;
for(int j=0;j<pos&&flag;++j)
{
if(step[j].y-step[j].x==step[pos].y-step[pos].x)flag=0;
if(step[j].y+step[j].x==step[pos].y+step[pos].x)flag=0;
if(step[j].y==step[pos].y)flag=0;
}
if(flag)
{
vis[i]=1;
dfs(pos+1,num);
vis[i]=0;
}
}
}
void init()
{
for(int i=1;i<=10;++i)
{
memset(vis,0,sizeof vis);
dfs(0,i);
}
}
int main()
{
init();
while(~scanf("%d",&n)&&n)
printf("%d\n",ans[n]);
return 0;
}