在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。
要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放 kk 个棋子的所有可行的摆放方案数目 CC。
输入格式
输入含有多组测试数据。
每组数据的第一行是两个正整数 n,kn,k,用一个空格隔开,表示了将在一个 n∗nn∗n 的矩阵内描述棋盘,以及摆放棋子的数目。当为-1 -1时表示输入结束。
随后的 nn 行描述了棋盘的形状:每行有 nn 个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目 CC (数据保证 C<231C<231)。
数据范围
n≤8,k≤nn≤8,k≤n
输入样例:
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
输出样例:2 1
OK啊,先上代码,注释看不懂,再看详解:
#include <iostream>
#include <vector>
#include<iomanip>
#include<cstdio>
using namespace std;
const int N = 10;
int n, k;//定义棋盘n*n 与 棋子数
char g[N][N]; // 建立地图 题目<=8
bool qs[N];//列定义 注意类型 表示的是有无 放过棋子
int fan = 0;//方案数
void dfs(int x, int cnt) {
if (cnt == k) {
fan++; return; // 棋子达到K 说明放不下了 方案+1 退出搜索
}
if (x >= n) {
return; // 行历遍完了 退出搜索
}
//开始枚举-面向行的
for (int i = 0; i < n; i++) {
if (qs[i] == false && g[x][i] == '#') { //这列没放过棋子
qs[i] = true; //现在你放过了
dfs(x + 1, cnt + 1); // 继续搜索下一行 cnt+1 为你放的棋子+1
qs[i] = false; //回溯
}
}
dfs(x + 1, cnt);//上面的for循环可能会产生这一行的每一列内都无法放置的问题 所以需要强制进行下一行 , 保证每一行都可以历遍.
}
int main() {
while (cin >> n >> k, n > 0 && k > 0) {
for (int i = 0; i < n; i++) {
scanf("%s", g[i]);
}//录入地图
fan = 0;//初始化方案数
dfs(0, 0);//从这个地图的第0行开始寻找,后面的0表示棋子数
printf("%d\n", fan);//输出这个实例的方案数
}
return 0;
}
=========================详细解说=====================
1.根据题目要求,我们需要创建地图,在创建完地图之后,我们需要根据题意(多组数据)使用while来多次输入数据.
2.在录入地图完毕之后,我们初始化了方案数,因为题目要求的是每个实例最后都要输出方案数,所以我们需要在每次while循环内去初始化它,防止它自己出现累加的情况,导致输出错误.
3.dfs(0,0)传入了2个int 类型, 前者代表的是行 意思是从第0行开始寻找,这和dfs的内容是挂钩的,第二个则是以放置的棋子数量默认为0,因为你一个棋子都还没有放置.
4.打印输出换行结果.
Main部分结束 DFS部分开始:==========================
1.我们用2个if来控制DFS的结束,第一个if是与棋子数挂钩的,因为你退出了这一次搜索,而且你这个方案的要求放置的棋子也已经放完了,所以你需要对方案数++.
2.x>=n是为了放置历遍的行出界,为什么还要等于n是因为二维数组的行列都是以0开始记的.
3.然后我们对行开始枚举,如果它没有放置过棋子且它是“#”,前者我们用qs这个bool进行判断,注意,这个qs是直接对该列起作用的,因为题目要求就是 在这一行这一列只能放置一个棋子,而我们对行进行枚举所以对列可以进行整列视为一的看待.
4.当我们发现这个位置可以进行棋子的放置,于是把qs该列标记为true,表示这列的状态不能放了,同时进行dfs(x + 1, cnt + 1)的操作 x+1是表示x的下一行 cnt+1 是表示放置的棋子数+1 .
5.如果这一行没办法操作,我们就需要通过回溯的方法,重新把qs[i]定义为false代表重新可用,然后通过最下面的dfs(x+1,cnt)来进行强制下一行的摆放尝试.
6.为什么要强制进行摆放尝试?因为我写在注释里面了.



610

被折叠的 条评论
为什么被折叠?



