zoukankan      html  css  js  c++  java
  • 八皇后问题

    题目描述

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

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

    行号 1 2 3 4 5 6

    列号 2 4 6 1 3 5

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

    输入格式:

    一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

    输出格式:

    前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

      典型的搜索期儿,本蒟蒻用了学会的DFS做的(严禁打表== ),我们每次试一下每一行的某个位置可不可以放下该棋子(该行肯定是事先没有的,确保列和两条对角线上有没有棋子即可),能放就放下,并标记为 1 (最后别忘了清除就好!),并用ans记录该答案,搜索完一行,继续搜索下一行,直至放满或搜索到最后一个格子 == 

    ·下面是本蒟蒻的代码,跑了756ms

     1 #include<cstdio>
     2 using namespace std;
     3 bool D[100],column[100];
     4 int ans[100],s,n;
     5 void DFS(int x){
     6     for(int i=1;i<=n;i++){
     7         int s1=i+x-1,s2=x-i+3*n-1;
     8         if(!D[s1]&&!D[s2]&&!column[i]){
     9             D[s1]=D[s2]=column[i]=1;
    10             if(s<=3) ans[x]=i;
    11             if(x<n) DFS(x+1);
    12             else{
    13                 s++;
    14                 if(s<=3){
    15                     for(int j=1;j<=n;j++) printf("%d ",ans[j]);
    16                     printf("\n");
    17                 }
    18             }
    19             D[s1]=D[s2]=column[i]=0;
    20         }
    21     }
    22 }
    23 int main()
    24 {
    25     scanf("%d",&n);
    26     DFS(1);
    27     printf("%d\n",s);
    28     return 0;
    29 }
    View Code

    ·下面是一位学长的代码,跑了672ms(比我的快←_←)

     1 #include<cstdio>
     2 using namespace std;
     3 const int maxn=20,maxm=40;
     4 bool column[maxn],L[maxm],R[maxm];
     5 bool M[maxn][maxn];
     6 int n,ans=0,num=0;
     7 int DFS(int x)
     8 {
     9     if(x==n)
    10     {
    11         num++;
    12         for(int i=0;i<=3;i++)
    13             for(int j=0;j<=n;j++)
    14                 if(M[i][j]&&num<=3)
    15                     printf("%d ",j);
    16         if(num<=3)
    17             printf("\n");
    18         ans++;
    19     }
    20     for(int i=1;i<=n;i++)
    21     {
    22         if(column[i]||L[x+i+1]||R[x-i+3])
    23             continue;
    24         M[x][i]=true;
    25         column[i]=L[x+i+1]=R[x-i+3]=true;
    26         DFS(x+1);
    27         M[x][i]=false;
    28         column[i]=L[x+i+1]=R[x-i+3]=false;
    29     }
    30     return ans;
    31 }
    32 int main()
    33 {
    34     scanf("%d",&n);
    35     DFS(0);
    36     printf("%d",ans);
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    20111013 18:32 女友刁钻无聊问题之标准答案
    20111013 17:40 学ACM有什么用
    typedef用法(1)
    深入C++的new(20111115 15:08 )
    用四个0算二十四点
    20111010 20:14 HDU 4021 (15数码)
    pku3020 Antenna Placement (解法1)
    C++箴言:理解typename的两个含义
    20110907 00:16 ubuntu 如何修改当前用户名
    vc6.0中添加msdn 20111105 11:52
  • 原文地址:https://www.cnblogs.com/RisingGods/p/8087263.html
Copyright © 2011-2022 走看看