문제 설명
N × m의 격자지도에서 폭탄이 특정 박스에 배치. 수동으로 폭탄이 폭탄을 폭발하는 모든 행과 열에서 폭탄 이후에 폭탄을 폭발하지만, 체인이 계속되도록 폭탄 폭발 폭탄, 다른 폭발.
이제 위험에 노출 된 정도를 최소화하기 위해 수동으로 폭탄을 폭발 일부하는 필요성을 모든지도에 폭탄을 폭파하기 위해,지도를 폭발 수동 적어도 모든 폭탄을 폭발 할 수 있습니다 얼마나 많은 폭탄 계산하시기 바랍니다.
입력 형식
두 정수 N, m의 제 1 전송 라인; N, m은 공간으로 분리된다.
다음 N 라인의지도 정보를 나타내는 입력 문자열 m의 각 라인의 길이.
0은 폭탄 1 개 폭탄을 의미한다.
데이터 규칙 :
데이터의 60 % : 1 <= N, m < = 100;
100 % 데이터 1 <= N,는 m < = 1000;
데이터보다 큰 입력 CIN 권장되지.
출력 형식
수동으로 폭탄을 폭파에 필요한 최소의 수를 나타냅니다를 출력 정수.
샘플 입력
5 5
00010
00010
01001
10001
01000
샘플 출력
2
샘플 코드 :
/**
该题说要算出手动引爆炸弹的最小个数
其实只要中规中矩从mp[0][0]按正常顺序遍历第一个炸弹开始引爆就可以了(想多的话还会特地找这个最小值,其实大可不必)
原因:
一个炸弹引爆会牵扯到一行炸弹和一列炸弹,被牵扯到的炸弹也会这样牵扯下去,产生连锁效应
*/
#include<cstdio>
char mp[1005][1005]; //存储地图信息
int n, m; //存储行列的值
int cnt; //用来记录手动引爆的次数
bool vx[1005], vy[1005]; //标记行列有没有被引爆(用来避免重复引爆)
void dfs(int x, int y ) {
//printf("(%d,%d)\n",x,y);
mp[x][y] = '0'; //被引爆的炸弹就置为0 避免重复引爆
if(!vx[x]) { // x 行没有被引爆则进行引爆
vx[x] = true; //x 行标记为 已引爆状态
for(int i = 0; i < m; i ++) { //在 x 行上寻找其他的炸弹
if(mp[x][i] == '1') { //找到炸弹则继续引爆该炸弹
dfs(x, i);
}
}
}
if(!vy[y]) { // y 列没有被引爆则进行引爆
vy[y] = true; //y 行列标记为 已引爆状态
for(int i = 0; i < n; i ++) { //在 y 列上寻找其他的炸弹
if(mp[i][y] == '1') { //找到炸弹则继续引爆该炸弹
dfs(i, y);
}
}
}
}
int main() {
scanf("%d%d",&n,&m);
for (int i = 0; i < n; i ++) {
scanf("%s",&mp[i]);
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j < m; j ++) {
if (mp[i][j] == '1') { //找到一个炸弹就开始手动引爆
cnt ++; //手动引爆次数 +1
dfs(i, j); //深搜传入炸弹的坐标
}
}
}
printf("%d\n", cnt);
return 0;
}