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

    Description

    会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 
    对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
    给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。

    Input

    第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)

    Output

    输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。

    Sample Input

    3
    6
    4
    25

    Sample Output

    25713864
    17582463
    36824175
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 //const double PI=acos(-1);
    17 #define Bug cout<<"---------------------"<<endl
    18 const int maxn=1e5+10;
    19 using namespace std;
    20 
    21 int vis[10];
    22 int A[10];
    23 int ans[93][10];
    24 int cnt=0;
    25 
    26 int judge(int n)
    27 {
    28     int flag=1;
    29     for(int i=1;i<=n;i++)
    30     {
    31         for(int j=1;j<=n;j++)
    32         {
    33             if(i!=j&&abs(i-j)==abs(A[i]-A[j]))  //别忘了i!=j 
    34                 flag=0;
    35         }
    36     }
    37     return flag;
    38 }
    39 
    40 void dfs(int p,int n)
    41 {
    42     A[n]=p;
    43     if(judge(n)==0)
    44         return ;
    45     if(n==8)
    46     {
    47         cnt++;
    48         for(int k=1;k<=8;k++)
    49             ans[cnt][k]=A[k];  //第一次写成ans[++cnt][k]=A[k]了。。。 
    50         return ;
    51     }
    52     for(int i=1;i<=8;i++)
    53     {
    54         if(vis[i]==0)
    55         {
    56             vis[i]=1;
    57             dfs(i,n+1);
    58             vis[i]=0;
    59         }
    60     }
    61 }
    62 
    63 int main()
    64 {
    65     for(int i=1;i<=8;i++)
    66     {
    67         vis[i]=1;
    68         dfs(i,1);
    69         vis[i]=0;
    70     }
    71     int T;
    72     scanf("%d",&T);
    73     while(T--)
    74     {
    75         int n;
    76         scanf("%d",&n);
    77         for(int i=1;i<=8;i++)
    78             printf("%d",ans[n][i]);
    79         printf("
    ");
    80     }
    81     return 0;
    82 }

    相似问题:

     

     样例输入:

    1  2  3  4  5  6  7  8
    9 10 11 12 13 14 15 16
    17 18 19 20 21 22 23 24
    25 26 27 28 29 30 31 32
    33 34 35 36 37 38 39 40
    41 42 43 44 45 46 47 48
    48 50 51 52 53 54 55 56
    57 58 59 60 61 62 63 64

    样例输出:

    260

    换了种写法,用列、主对角线和副对角线来判断

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <string>
    #include <math.h>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #include <sstream>
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    const int mod=1e9+7;
    const double PI = acos(-1);
    #define Bug cout<<"---------------------"<<endl
    const int maxn=1e4+10;
    using namespace std;
    
    int G[9][9];
    int jm[3][20];
    int ans;
    
    void DFS(int num,int sum)
    {
        if(num>8)
        {
            ans=max(ans,sum);
            return;
        }
        for(int i=1;i<=8;i++)
        {
            if(jm[0][i]==0&&jm[1][num-i+8]==0&&jm[2][num+i]==0)
            {
                jm[0][i]=jm[1][num-i+8]=jm[2][num+i]=1;
                DFS(num+1,sum+G[i][num]);
                jm[0][i]=jm[1][num-i+8]=jm[2][num+i]=0;
            }
        }
    }
    
    int main()
    {
        #ifdef DEBUG
        freopen("sample.txt","r",stdin);
        #endif
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        for(int i=1;i<=8;i++)
        {
            for(int j=1;j<=8;j++)
            {
                scanf("%d",&G[i][j]);
            }
        }
        DFS(1,0);
        printf("%d
    ",ans);
        
        return 0;
    }

    Description

      给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

    Input

      输入的第一行为一个整数n,表示棋盘的大小。
    接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

    Output

      输出一个整数,表示总共有多少种放法。

    Sample Input

    4
    1 1 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1

    Sample Output

    2
     1 #include <string>
     2 #include <math.h>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <stack>
     6 #include <queue>
     7 #include <set>
     8 #include <map>
     9 #include <sstream>
    10 const int INF=0x3f3f3f3f;
    11 typedef long long LL;
    12 const int mod=1e9+7;
    13 //const double PI=acos(-1);
    14 #define Bug cout<<"---------------------"<<endl
    15 const int maxn=1e5+10;
    16 using namespace std;
    17 
    18 int G[10][10];
    19 int vis[10];
    20 int tem[10];
    21 int ans[100][10];
    22 int cnt;
    23 
    24 int judge(int step,int n)
    25 {
    26     for(int i=1;i<=step;i++)
    27     {
    28         for(int j=1;j<=step;j++)
    29         {
    30             if(i!=j&&abs(i-j)==abs(tem[i]-tem[j]))
    31                 return 0;
    32         }
    33     }
    34     return 1;
    35 }
    36 
    37 void DFS(int step,int n)
    38 {
    39     if(judge(step,n)==0)
    40         return ;
    41     if(step==n)
    42     {
    43         cnt++;
    44         for(int k=1;k<=n;k++)
    45             ans[cnt][k]=tem[k];
    46         return ;
    47     }
    48     for(int i=1;i<=n;i++)
    49     {
    50         if(!vis[i]&&G[step+1][i])
    51         {
    52             vis[i]=1;
    53             tem[step+1]=i;
    54             DFS(step+1,n);
    55             vis[i]=0;
    56         }
    57     }
    58 }
    59 
    60 void Solve(int n)
    61 {
    62     int num=0;
    63     for(int i=1;i<=cnt;i++)
    64     {
    65         for(int j=i+1;j<=cnt;j++)
    66         {
    67             int k;
    68             for(k=1;k<=n;k++)
    69             {
    70                 if(ans[i][k]==ans[j][k])
    71                     break;
    72             }
    73             if(k>n)
    74                 num++;
    75         }
    76     }
    77     printf("%d
    ",num*2);
    78 }
    79 
    80 int main()
    81 {
    82     int n;
    83     scanf("%d",&n);
    84     for(int i=1;i<=n;i++)
    85         for(int j=1;j<=n;j++)
    86             scanf("%d",&G[i][j]);
    87     for(int i=1;i<=n;i++)
    88     {
    89         if(G[1][i])
    90         {
    91             vis[i]=1;
    92             tem[1]=i;
    93             DFS(1,n);
    94             vis[i]=0;
    95         }
    96     }
    97     Solve(n);
    98     return 0;
    99 }
  • 相关阅读:
    详解EBS接口开发之采购申请导入
    EBS HRMS数据表
    会计期间
    帐套和会计科目的理解
    oracle中动态SQL详解
    不同币种汇率转换
    API创建/更新员工联系电话
    API创建/更新员工薪水
    Android 圆形、圆角图片ImageView
    Knowledge Generation Model for Visual Analytics
  • 原文地址:https://www.cnblogs.com/jiamian/p/11723630.html
Copyright © 2011-2022 走看看