• 蓝桥杯 基础训练 2n皇后


      数月前做的2N皇后基本看书敲代码的,然后发现当时的代码不对,正好做到算法提高的8皇后·改,顺便把以前的代码顺带改了下,题目如下:

    问题描述
      给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
    输入格式
      输入的第一行为一个整数n,表示棋盘的大小。
      接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
    输出格式
      输出一个整数,表示总共有多少种放法。
    样例输入
    4
    1 1 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    样例输出
    2
    样例输入
    4
    1 0 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    样例输出
    0
    ---------分割线---------
      书上的回溯法写起来未免比较麻烦,《算法竞赛入门经典》中就对N后问题有个方便的写法,就是用2维数组vis[3][2n]来判断当前是否可放皇后,第一行代表当前列是否已放过,第2、3行代表当前位置的斜线是否已放过;至于此题是黑白两色皇后,把所有单色皇后可行方案放在2维数组里,然后2个for循环判断两个方案是否有共同使用的位置,若无,则方案数+1,具体可见代码:
     1 #include<stdio.h>
     2 int a[8][8];
     3 int vis[3][20];
     4 int b[8];
     5 int c[100][8];
     6 int n;
     7 int count=0;
     8 void dfs(int cur)
     9 {
    10     int i;
    11     if(cur==n)
    12     {
    13         for(i=0;i<n;i++)
    14             c[count][i]=b[i];
    15         count++;
    16     }
    17     else for(i=0;i<n;i++)
    18     {
    19         if(a[cur][i]&&!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])
    20         {
    21             b[cur]=i;
    22             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
    23             dfs(cur+1);
    24             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
    25         }
    26     }
    27 }
    28 int main()
    29 {
    30     int i,j,k,number=0,flag;
    31     scanf("%d",&n);
    32     for(i=0;i<n;i++)
    33         for(j=0;j<n;j++)
    34             scanf("%d",&a[i][j]);
    35     dfs(0);
    36     for(i=0;i<count;i++)
    37     {
    38         for(j=i+1;j<count;j++)
    39         {
    40             flag=1;
    41             for(k=0;k<n;k++)
    42             {
    43                 if(c[i][k]==c[j][k])
    44                 {
    45                     flag=0;
    46                     break;
    47                 }
    48             }
    49             if(flag)
    50                 number++;
    51         }
    52     }
    53     printf("%d",number*2);
    54     return 0;
    55 }
  • 相关阅读:
    Windows Server 2008搭建AD域控服务器
    远程桌面出现CredSSP解决方案
    破解Excel工作表保护,清除所有密码并获取密码
    Windows Server 2008 R2 搭建NTP时间服务器
    VMware Tools
    windows常用运行命令
    无线AP与AC详解
    单臂路由
    ACL控制指定IP访问限制
    Linux下安装VMware
  • 原文地址:https://www.cnblogs.com/search-the-universe/p/last_month_3.html
Copyright © 2020-2023  润新知