poj 1321 棋盘问题 dfs
来源:互联网 发布:剑网南风捏脸米苏数据 编辑:程序博客网 时间:2024/06/06 11:42
C - 北京大学推免生机考D题
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & %lluDescription
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同
一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 ,
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 ,
k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1#..#4 4...#..#..#..#...-1 -1
Sample Output
21
思路:一道比较简单的dfs题目,有点类似N皇后问题,我用了两种方法,因为这个问题要求我们放的棋子数k可能少于棋盘的n,
也可能相等,如果相等话好说每一行每一列上都有,直接dfs标记一下就行了,我们需要考虑的就是k<n的时候;
第一种:我是标记的列然后每次对行dfs就不会放在同行同列了
#include<stdio.h>#include<string.h>char a[10][10];int s[10][10];int flag[10];int n,k,count;void dfs(int row,int num){ int i; if(num==k) { count++; return ; } if(row>=n) return ; for(i=0;i<n;i++) { if(s[row][i]==1&&flag[i]==0) { flag[i]=1; dfs(row+1,num+1); flag[i]=0;} } dfs(row+1,num);//这个地方可能比较难理解,这是对k<n情况的处理,当放完这一行,回溯的时候,因为k<n,所以我们要跳过这一行去找下一行满足条件的,一直到row》=n结束;}int main(){ while(scanf("%d %d",&n,&k)!=EOF) { if(n==-1&&k==-1) break; memset(flag,0,sizeof(flag)); memset(s,0,sizeof(s)); count=0; int i,j; for(i=0;i<n;i++) scanf("%s",a[i]); for(i=0;i<n;i++) for(j=0;j<n;j++) { if(a[i][j]=='#') s[i][j]=1; else s[i][j]=0;} dfs(0,0); printf("%d\n",count); } return 0;}第二种方法:
//我是这样想的,如果k<n,那么第一个棋子最大只能放到第n-k行(从0开始),那么他的下一行最大只能放到n-num+1行,也是标记列,对行dfs,得出结果,还挺快的0ms本人搜索学的比较糙,如果哪里不对,或者大神有更好的见解,欢迎大家留言一起交流!#include<stdio.h>#include<string.h>char a[10][10];int s[10][10];int flag[10];int n,k,count;void dfs(int row,int num){ int i,j; for(j=0;j<n;j++) { if(s[row][j]==1&&flag[j]==0) { if(num==1) { count++; } else { flag[j]=1; for(i=row+1;i<n-num+2;i++) dfs(i,num-1); flag[j]=0; } } }}int main(){ while(scanf("%d %d",&n,&k)!=EOF) { if(n==-1&&k==-1) break; memset(flag,0,sizeof(flag)); memset(s,0,sizeof(s)); count=0; int i,j; for(i=0;i<n;i++) scanf("%s",a[i]); for(i=0;i<n;i++) for(j=0;j<n;j++) { if(a[i][j]=='#') s[i][j]=1; else s[i][j]=0;} for(i=0;i<=n-k;i++) dfs(i,k); printf("%d\n",count); } return 0;}
1 0
- POJ 1321 棋盘问题(棋盘DFS)
- POJ 1321 棋盘问题 DFS
- POJ 1321 棋盘问题 (dfs)
- poj 1321 -- 棋盘问题 (DFS)
- poj 1321 :棋盘问题 (dfs)
- poj 1321 棋盘问题(DFS)
- POJ 1321 棋盘问题(DFS)
- poj 1321 棋盘问题 【DFS】
- poj 1321 棋盘问题 (dfs)
- 棋盘问题 POJ 1321 DFS
- POJ 1321 棋盘问题 (DFS)
- POJ 1321-棋盘问题(dfs)
- POJ 1321 棋盘问题(DFS)
- DFS-POJ-1321-棋盘问题
- POJ 1321--棋盘问题【DFS】
- poj 1321 棋盘问题 (dfs)
- POJ 1321 棋盘问题 dfs
- poj-1321 棋盘问题 DFS
- 【scrapy】item传递出错
- 有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
- 算法----hanoi塔问题(Java)
- 散列表(哈希表)查找
- 数据库的基本操作之删除(单/多)列
- poj 1321 棋盘问题 dfs
- Web应用程序状态管理
- 11111
- eclipse运行Tomate可以连接上数据库,打包成war包 部署数据库连不上
- 对于任意正整数,都可以找出至少一串连续奇数,他们的和等于该整数的立方,验证【2,20】
- JAVA进阶案例 TCP编程之网络聊天工具(客户端)
- Q1--二维数组中的查找
- MySQL忘记数据库root用户密码和修改root用户密码
- memmove 和 memcpy的区别