八皇后问题

检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:

行号 1 2 3 4 5 6

列号 2 4 6 1 3 5

这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。

//以下的话来自usaco官方,不代表洛谷观点

特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号删除并且不能参加USACO的任何竞赛。我警告过你了!

如果这样,会超时

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=23;
 5 int n,map[maxn][maxn],ans[maxn][maxn],cnt;
 6 bool check(int x){
 7   int j=x/n;
 8   for(int i=0;i<n;i++){
 9     if(map[j][i]==1) return false;
10   } 
11   j=x%n;
12   for(int i=0;i<n;i++){
13     if(map[i][j]==1) return false;
14   }
15   int xx=x/n;int yy=x%n;
16   for(int i=1;i<n;i++){
17     if(
18   } 
19 }
20 void dfs(int x){
21   if(x>=n*n-1){
22     cnt++;
23     if(cnt<=3){
24       for(int i=0;i<9;i++)
25         for(int j=0;j<9;j++){
26           if(map[i][j]==1){ans[cnt][i]=j;continue;}
27         }
28     }
29     return;
30   }
31   dfs(x+1);
32   if(check(x)){map[x/n][x%n]=1;dfs(x+1);map[x/n][x%n]=0;}
33 }
34 int main(){
35   cin>>n;
36   dfs(0);
37   for(int i=1;i<=3;i++){
38     for(int j=0;j<n;j++) cout<<ans[j]<<" ";
39     cout<<endl;
40   }
41   cout<<cnt<<endl;
42   return 0;
43 } 

最好打标记,注意对角线的性质

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn=207;
 7 int n,ans_top,pos[maxn];
 8 bool h[maxn],l[maxn],r[maxn];
 9 bool check(int x){
10   int i=pos[x];
11   if(h[i]==true||r[x+i]==true||l[x-i+37]==true) return false;
12   return true;
13 } 
14 void dfs(int x){
15     if(x==n){
16       ans_top++;
17       if(ans_top<=3){
18         for(int i=0;i<n;i++){
19           cout<<pos[i]+1<<" ";
20         }cout<<endl; 
21       }
22     } 
23   for(int i=0;i<n;i++){
24     pos[x]=i;
25     if(check(x)){
26       pos[x]=i;h[i]=true;r[x+i]=true;l[x-i+37]=true;
27       dfs(x+1);
28       h[i]=false;r[x+i]=false;l[x-i+37]=false;
29     }
30   }
31 }
32 int main(){
33   memset(pos,-1,sizeof(pos));
34   cin>>n;
35   dfs(0);
36   cout<<ans_top<<endl;
37   return 0;
38 }

 

posted @ 2018-09-14 21:43  lcan  阅读(203)  评论(0编辑  收藏  举报