原题连接html
在一个 n × m n×m n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹之后,
炸弹会把炸弹所在的行和列上的全部炸弹引爆,被引爆的炸弹又能引爆其余炸弹,这样连锁下去。
如今为了引爆地图上的全部炸弹,须要手动引爆其中一些炸弹
为了把危险程度降到最低,请算出最少手动引爆多少个炸弹能够把地图上的全部炸弹引爆。ios输入格式
第一行输两个整数 n , m n,m n,m用空格隔开。
接下来 n n n 行,每行输入一个长度为 m m m 的字符串,表示地图信息。0
表示没有炸弹,1
表示炸弹。
数据约定:
对于 60 % 60\% 60% 的数据: 1 ≤ n , m ≤ 100 1≤n,m≤100 1≤n,m≤100;
对于 100 % 100\% 100% 的数据: 1 ≤ n , m ≤ 1000 1≤n,m≤1000 1≤n,m≤1000;
数据量比较大,不建议用cin
输入。web输出格式
输出一个整数,表示最少须要手动引爆的炸弹数。svg
输入样例
5 5 00010 00010 01001 10001 01000输出样例
2
炸弹会把炸弹所在的行和列上的全部炸弹引爆,被引爆的炸弹又能引爆其余炸弹,这样连锁下去
因此处于同一连通块的炸弹的引爆顺序不会对答案形成影响, 只要引爆一个炸弹, 和该炸弹处于同一连通块的炸弹都会相继被引爆
根据这一特色, 进行深搜
注意剪枝: 同一行(列)只引爆一次, 不然会超时spa
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int N = 1009; int n, m; int map[N][N]; bool row[N], col[N]; int sum; void dfs(int x, int y) // 将与(x,y)处于同一连通块的炸弹引爆 { if(!col[y]) // 剪枝 { col[y] = 1; for(int i=0; i<n; i++) { if(map[i][y] == 1) { map[i][y] = 0; dfs(i, y); } } } if(!row[x]) // 剪枝 { row[x] = 1; for(int i=0; i<m; i++) { if(map[x][i] == 1) { map[x][i] = 0; dfs(x, i); } } } return; } int main() { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) for(int j=0; j<m; j++) scanf("%1d",&map[i][j]); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(map[i][j] == 1) { sum++; map[i][j] = 0; dfs(i, j); } } } cout << sum << endl; return 0; }