引爆炸弹
在一个n*m的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把其所在的行和列的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。
现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
输入格式
第一行输入两个正数n,m,用空格隔开。
接下来n行,每行输入一个长度为m的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。
数据约定:
对于60%的数据:1<=n,m<=100;
对于100%的数据:1<=n;m<=1000;
输出格式
输出一个证书,表示最少需要手动引爆的炸弹数。
样例输入
5 5
00010
00010
01001
10001
01000
样例输出
2
本题思路
本题首先不要纠结炸弹的个数,要把可以连锁引爆的炸弹当做一个集合,每个集合分别引爆一个炸弹,便能将所有炸弹引爆。因此本题将手动引爆最少的炸弹个数,转化为求炸弹的集合数。
递归参数:地图坐标x,y
递归边界:当前行列是否被访问过
递归体:遍历所在行,列,如果有炸弹,继续引爆
剪枝:visx[], visy[], mp[x][y] = ‘0’,以保证行列只访问一次
也可能是本题有点抽象,自己解读题意,将其转换为算法的能力不够。
个人思路
解这道题,对于题意的理解和个人思路都非常有问题。
首先是题意重点理解错误:一直盯着最少两个字不放,一直在考虑要引爆哪几个炸弹才能达到最少的题目要求,并一度考虑对地图中所有炸弹逐个遍历,用mincnt记录 过程中引爆炸弹的次数,看从哪里引爆才能得到最少的答案,并一再发问,为什么dfs得到的答案就能保证数量最少?
并把当前引爆炸弹的个数作为递归参数,当已经引爆的炸弹数等于总的炸弹个数作为递归边界,并设置mincnt记录并比较过程中需要手动引爆的炸弹数
要明确!!!
此题中的手动引爆次数最少,并不是指智能引爆特定的一两个,才能达到题意的要求,而是只要不同炸弹集合中引爆一个,即可全部引爆,也就是求炸弹的集合数
确实还是自己太菜了,仍需努力啊!
编程中的细节错误
- 递归边界的书写问题
if(visx[x] || visy[y])
return;
将上述条件作为递归边界会导致:某方格其行被标记,列未被标记时,由于此判断条件导致无法对列进行访问。</