hdu2553N皇后问题

来源:互联网 发布:移动网络变成电信 编辑:程序博客网 时间:2024/06/05 17:23

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553

题目

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7696    Accepted Submission(s): 3462


Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

 

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
 

Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 

Sample Input
1850
 

Sample Output
19210
 

Author
cgf
有两种解法:

第一种没有优化的,用时间换空间。。第二种优化的,用空间换时间。。。

使用递归就要注意递归边界,否则会出现无穷递归。。。还要找到满足条件。。

第一种是从行开始搜索,然后遍历列,然后是遍历cur前面的行,是否与现在放置的皇后产生冲突。。

因为不能同行,同列,同对角线。。所以条件cur-C[cur]=j-C[j]或者cur+C[cur]=j+C[j]..可以通过行列式得出规律。。

还有就是要注意打表。。不然会超时。。。。

代码如下:

#include<cstdio>#include<cstring>const int maxn=100;int n,tot,C[maxn],pos[maxn];void  dfs(int cur,int n,int k){    int i,j;    if(cur==n) pos[k]++;    else    {        for(i=0;i<n;i++)//遍历列      {         int ok=1;         C[cur]=i;         for(j=0;j<cur;j++)//遍历上面的行           {              if(C[cur]==C[j]||cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j])              ok=0;           }        if(ok)         dfs(cur+1,n,k);      }    }}int main(){        int i;        memset(C,0,sizeof(C));        memset(pos,0,sizeof(pos));        for(i=0;i<11;i++)           dfs(0,i,i);           while(scanf("%d",&n)!=EOF)           {               if(n==0) return 0;               printf("%d\n",pos[n]);           }    return 0;}

第二种是三个数组来进行优化。减少一重循环。。。

vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;

注意一定要最后把标记改回来。。。

代码如下

#include<cstdio>#include<cstring>const int maxn=100;int n,tot,C[maxn],pos[maxn];int vis[3][maxn];void  Dfs(int cur,int n,int k){     int i,j;    if(cur==n) pos[k]++;    else    {        for(i=0;i<n;i++)//遍历列      {         if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])         {             C[cur]=i;             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;             Dfs(cur+1,n,k);             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;         }       }    }}int main(){        int i;        memset(C,0,sizeof(C));        memset(pos,0,sizeof(pos));        for(i=0;i<11;i++)            Dfs(0,i,i);        while(scanf("%d",&n)!=EOF)           {               if(n==0) return 0;               printf("%d\n",pos[n]);           }    return 0;}

这是八皇后经典算法。。。加油。。。!!!!

0 0
原创粉丝点击