hdu 2553 N皇后问题 (DFS)

N皇后问题

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


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

 

 

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

 

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

 

Sample Input
1 8 5 0
 

 

Sample Output
1 92 10
 

 

Author
cgf
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  2614 1258 1426 1175 1067 
 
 1 //31MS    256K    993 B    C++
 2 //经典N皇后问题 深搜解法 
 3 #include<stdio.h>
 4 #include<string.h>
 5 int cnt,n;
 6 int q[15][15];
 7 int Judge(int x,int y)
 8 {
 9     for(int i=0;i<n;i++) if(q[x][i] && i!=y) return 0;
10     for(int i=0;i<n;i++) if(q[i][y] && i!=x) return 0;
11     for(int i=x+1,j=y+1;i<n && j<n;i++,j++)
12         if(q[i][j]) return 0;
13     for(int i=x-1,j=y-1;i>=0 && j>=0;i--,j--)
14         if(q[i][j]) return 0;
15     for(int i=x+1,j=y-1;i<n && j>=0;i++,j--)
16         if(q[i][j]) return 0;
17     for(int i=x-1,j=y+1;i>=0 && j<n;i--,j++)
18         if(q[i][j]) return 0;
19     return 1;
20 }   
21 void dfs(int c)
22 {
23     if(c==n){ cnt++;return;}
24     for(int i=0;i<n;i++)
25         if(Judge(i,c)){
26             q[i][c]=1;
27             dfs(c+1);
28             q[i][c]=0;
29         }
30 }
31 int main(void)
32 {
33     int a[15]={0};//不打表会超时 
34     for(int i=1;i<11;i++){
35         n=i;
36         cnt=0;
37         memset(q,0,sizeof(q));
38         dfs(0);
39         a[i]=cnt;
40     }
41     while(scanf("%d",&n)!=EOF && n)
42     {
43         printf("%d\n",a[n]);
44     }
45     return 0;
46 } 

 

 

给出一个高效的位运算求法:

 1 //15MS    208K    704 B    G++ 
 2 #include<stdio.h>
 3 int ans[15];
 4 int sum;
 5 int upperlim;
 6 void dfs(int row,int ld,int rd) //某行中纵列不可取,左右对角线不可取的限制条件 
 7 {
 8     int pos,p;
 9     if(row!=upperlim){
10         pos=upperlim&(~(row|ld|rd)); //取出可以放的位置 
11         while(pos){
12             p=pos&(~pos+1); //取pos最左边的1 
13             pos=pos-p;   //减去可取的 
14             dfs(row|p,(ld|p)<<1,(rd|p)>>1); //深搜 
15         }
16     }else sum++; //搜出来后总数+1 
17 }
18 int main(void)
19 {
20     for(int i=1;i<11;i++){
21         sum=0;
22         upperlim=(1<<i)-1; //i个1
23         dfs(0,0,0);
24         ans[i]=sum;
25     }
26     int n;
27     while(scanf("%d",&n),n)
28     {
29         printf("%d\n",ans[n]);
30     }
31     return 0;
32 } 

 

posted @ 2013-12-16 21:05  heaventouch  阅读(251)  评论(0编辑  收藏  举报