• 棋盘问题(深搜,统计)


    棋盘问题

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
    Total Submission(s) : 48   Accepted Submission(s) : 22
    Problem Description
    在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
     
    Input
    输入含有多组测试数据。 
    每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
    当为-1 -1时表示输入结束。 
    随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 
     
    Output
    对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
     
    Sample Input
    2 1
    #.
    .#
    4 4
    ...#
    ..#.
    .#..
    #...
    -1 -1
     
    Sample Output
    2
    1
     
    Source
    PKU

    题意:

    思路:

    棋盘问题, 棋子摆放的位置只能是#, 且不能同行和同列. 由于我采用的是按行递增的顺序来搜索的, 因此不可能出现同行的情况, 对于同列的情况, 我设置了一个变量col[], 来保存列的访问状态, 对于之前访问过的列, 棋子是不能再放在这一列上的,true表示该列可以放,false表示该列不可以放DFS(i, j) 代表将第j棵棋子放在i行上。

    还是看代码吧,代码里面有注释的。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<vector>
     6 
     7 
     8 using namespace std;
     9 bool col[10]={true};//存储第i列可以放棋子吗,true表示可以,false表示不可以
    10 bool s[10][10]={false};//s[i][j]==true表示点(i,j)可以存放棋子,s[i][j]==false表示点(i,j)不可以存放棋子
    11 int n,k;
    12 int number=0;
    13 
    14 
    15 
    16 bool DFS(int m,int sum)//深搜函数,DFS(i,j)代表第j个棋子可能放在第i行
    17 {
    18     if(m<=n+1&&sum==k+1){
    19         number++;
    20         return true;
    21     }
    22     if(m==n+1){
    23         return false;
    24     }
    25     for(int i=1;i<=n;i++)
    26     {
    27         if(s[m][i]&&col[i]){//s[m][i]==true表示第m行第i列可以存放棋子,col[i]==true表示第i列可以存放棋子,一定要注意着我在这WA了好几次
    28             col[i]=false;//第i列不再可以存放棋子
    29             DFS(m+1,sum+1);
    30             col[i]=true;//还原棋盘形状
    31         }
    32     }
    33     DFS(m+1,sum);//第m行不放棋子,定义为空行
    34 }
    35 
    36 
    37 int main()
    38 {
    39 //    freopen("1.txt","r",stdin);
    40     while(cin>>n>>k){
    41         if(n==k&&n==-1)
    42         break;
    43         memset(s,false,sizeof(s));
    44         for(int i=1;i<=n;i++){
    45             for(int j=1;j<=n;j++){
    46                 char a;
    47                 cin>>a;
    48                 if(a=='#')
    49                     s[i][j]=true;
    50             }
    51         }
    52         memset(col,true,sizeof(col));
    53         number=0;//*******一定要将number置0
    54         DFS(1,1);
    55         cout<<number<<endl;
    56     }
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    【Python基础知识】【语法】【入门】
    linux-记录一次VMWare安装linux的问题
    mysql-记录一次CentOS7压缩包安装mysql的过程
    java-记录一次新服务器搭建网站过程
    docker-mysql-记录一次中文乱码的问题。
    spring-事务总结
    spring-aop总结
    maven-spring-boot-first-version-learn编译运行的问题
    maven-导入4.0.0.BOOTSTRAP-SNAPSHOT遇到的问题。
    maven-添加spring-express snapshot版本依赖问题
  • 原文地址:https://www.cnblogs.com/zhangchengbing/p/3365585.html
Copyright © 2020-2023  润新知