Problem ID:1019 N皇后问题
简单题意: 在N*N的棋盘上放N个皇后,任意2个皇后不允许处在同一排,同一列,也不允许连线与棋盘边框成45°角。给定N,求出所有的放置方法数。(正整数N<=10)
解题思路形成过程:利用深搜对行和列 先后 进行遍历,记录下当前位置之前所有行放置位置的列号。
在遍历过程中,所有要放置的皇后必须同时满足3个要求,即:和之前放置好的皇后不处在同一行、同一列,连线不成45°角。如果不完全符合这3个要求,则判断如果放置在下一列是否符合要求;如果符合这3个要求,则直接到下一行从第一列开始遍历。
当遍历到最后一行时,当有符合要求的位置时,返回1;否则,返回0。
感想:①不要想当然,不是每一行都一定会有一个符合要求的位置。
②必须提前打表,N为1-10,将所有结果提前储存到数组中,否则会超时。
代码:
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
int total;
int dfs(int rs[10],int r)//r:当前行号
{
int cnt=0;
if(r==total){
return 1;
}
for(int i=0;i<total;++i){//i:当前行的列号
int t=0;
for(int j=0;j<r;++j)//j:第j行
if(i==rs[j]||abs(i-rs[j])==r-j){//r[j]:第j行的列号
++t;
break;
}
if(t==0){
rs[r]=i;
cnt+=dfs(rs,r+1);
}
}
return cnt;
}
int main()
{
//freopen("2.txt","r",stdin);
/*while(1) //如果这样写会超时!
{
scanf("%d",&total);
int n,rs[10],o[10];
if(total==0)
return 0;
n=dfs(rs,0);
printf("%d\n",n);
}*/
int rs[10],o[10];
for(int i=1;i<=10;++i){
total=i;
o[i-1]=dfs(rs,0); //必须提前打表。
}
int t;
while(cin>>t){
if(t==0)
return 0;
printf("%d\n",o[t-1]);
}
}