zoukankan      html  css  js  c++  java
  • 1432. 棋盘挑战

    给定一个 N×N 的棋盘,请你在上面放置 N 个棋子,要求满足:

    • 每行每列都恰好有一个棋子
    • 每条对角线上都最多只能有一个棋子
        1   2   3   4   5   6
      -------------------------
    1 |   | O |   |   |   |   |
      -------------------------
    2 |   |   |   | O |   |   |
      -------------------------
    3 |   |   |   |   |   | O |
      -------------------------
    4 | O |   |   |   |   |   |
      -------------------------
    5 |   |   | O |   |   |   |
      -------------------------
    6 |   |   |   |   | O |   |
      -------------------------
    

    上图给出了当 N=6 时的一种解决方案,该方案可用序列 2 4 6 1 3 5 来描述,该序列按顺序给出了从第一行到第六行,每一行摆放的棋子所在的列的位置。

    请你编写一个程序,给定一个 N×N的棋盘以及 NN个棋子,请你找出所有满足上述条件的棋子放置方案。

    输入格式

    共一行,一个整数 N

    输出格式

    共四行,前三行每行输出一个整数序列,用来描述一种可行放置方案,序列中的第 ii个数表示第 ii行的棋子应该摆放的列的位置。

    这三行描述的方案应该是整数序列字典序排在第一、第二、第三的方案。

    第四行输出一个整数,表示可行放置方案的总数。

    数据范围

    6N13

    输入样例:

    6
    

    输出样例:

    2 4 6 1 3 5
    3 6 2 5 1 4
    4 1 5 2 6 3
    4


    这题就是八皇后,就是输出的时候需要注意一下格式,只需要我们输出前三种方案和方案总数,那么只需要在输出的代码前加上约束条件,if(ans<=3)时,进行输出
    八皇后的难点就是如何对不符合要求的格子进行染色:

    皇后所在的行和列以及斜边不能够有别的皇后在,否则便会相互攻击到。

    因为我们使用深搜的每一层递归相当于是一行,在每一次递归当中选中其中的一列,所以可以定义一个r数组和一个c数组以及L数组和R数组,相当于皇后所在的行和列以及斜边上进行染色

     

    对于斜边 : y = kx+b; 等价于 b=y-kx; 需要注意的是 k=1或k=-1;

    所以 b=y-x 或者 b=y+x

     

    因为y-x有可能小于0,所以我们需要加上一个参数把它的值调回正数

    所以数组染色的表示为 r[x] , c[i] ,L[y+x] ,R[y-x+10];

    重申:r[x]表示这一行是否有皇后 、 c[i]表示这一列是否有皇后

     

    因为本题对无解的n和n==1时没有特殊要求,所以只需要考虑一般情况,具体代码如下:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 const int N = 20;
     5 int a[N]; 
     6 int c[N],r[N],L[N],R[N];
     7 int ans;
     8 int n;
     9 
    10 inline bool check(int x,int y){
    11     if( x<1 || x>n ||y<1 || y>n)  return 0;  //地图之外不能放棋子 
    12     if(r[x] || c[y] || L[y+x] || R[y-x+10]) return 0; //染色了的格子也不能放 
    13     return 1;
    14  }
    15 
    16 inline void dfs(int x){
    17     if(x>n){  //递归出口 
    18         ans++;
    19         if(ans<=3){  //约束条件 
    20             for(int i = 1;i<=n;++i){
    21                 printf("%d ",a[i]);
    22             }
    23             printf("
    ");
    24         }
    25         return ;
    26     }
    27     
    28     for(int i = 1;i<=n;++i){
    29         if(check(x,i)){
    30             r[x] = c[i] = 1;
    31             L[i+x] = R[i-x+10] = 1;
    32             a[x] = i; 
    33             //进入下一层递归 
    34             dfs(x+1);
    35             //记得要回溯 
    36             r[x] = c[i] = 0;
    37             L[i+x] = R[i-x+10] = 0;
    38         }
    39     }
    40 }
    41 
    42 
    43 int main()
    44 {
    45     scanf("%d",&n);
    46     ans = 0;
    47     dfs(1);
    48     printf("%d
    ",ans);
    49     return 0;
    50  } 
  • 相关阅读:
    魅族Java面经
    笔试常考的Java基础
    笔试常考的Linux命令大全
    Spring概念
    Java三大框架的配置
    Myeclipse的使用
    项目经验
    Android四大组件及activity的四大启动模式
    java基础
    IT在线笔试总结(二)
  • 原文地址:https://www.cnblogs.com/ssfannnnn/p/14312405.html
Copyright © 2011-2022 走看看