1.6.3 棋盘问题1

举报
irrational 发表于 2022/01/17 22:54:21 2022/01/17
【摘要】 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。 要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列。请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。 Input 输入含有多组测试数据。 每组数据的第一行是两个正整数,n,k用一个空格隔开,表...

Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。
要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列。请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。

每组数据的第一行是两个正整数,n,k用一个空格隔开,表示了将在一个n∗n的矩阵内描述棋盘,以及摆放棋子的数目。

当为−1−1时表示输入结束。

随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

Output

对于每一组数据,给出一行输出,输出摆放的方案数目CCC。

Sample Input 1

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output 1

2
1

  
  1. //DFS
  2. //类似于八皇后的一道多了一些限制的题
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <cstring>
  6. using namespace std;
  7. const int N = 20;
  8. char g[N][N]; //存储输入棋盘
  9. int ans; //存储答案
  10. int n, k;
  11. int m; //存储已近放入棋盘的棋子数
  12. bool line[N]; //存储当前列上有没有其他棋子
  13. void dfs(int x)
  14. {
  15. if(m == k) //当棋子放光的时候
  16. {
  17. ans++;
  18. return;
  19. }
  20. if(x == n) //防止越界
  21. return;
  22. for(int i = 0; i < n; i++) //直接dfs简单完事 按着列的顺序依次向下
  23. if(!line[i] && g[x][i] == '#')
  24. {
  25. line[i] = true;
  26. m++; //记录放入的棋子数
  27. dfs(x + 1);
  28. line[i] = false; //还原初始状态
  29. m--;
  30. }
  31. dfs(x + 1);
  32. //这个是关键,因为 k <= m,因此可能有的行不能放棋子,所以我们要手动舍弃行,直接进入下一行,以免有的情况被遗漏
  33. }
  34. int main()
  35. {
  36. while(scanf("%d%d", &n, &k) && n != -1 && k != -1)
  37. {
  38. ans = m = 0;
  39. for(int i = 0; i < n; i++)
  40. for(int j = 0; j < n; j++)
  41. cin >> g[i][j];
  42. dfs(0);
  43. cout << ans << endl;
  44. }
  45. return 0;
  46. }

大家可以比划着自己手动模拟一下。

文章来源: blog.csdn.net,作者:irrationality,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54227557/article/details/120606666

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。