nyoj 27-水池数目(BFS, DFS)
27-水池数目
内存限制:64MB
时间限制:3000ms
Special Judge: No
accepted:17
submit:22
题目描述:
南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水池。
输入描述:
第一行输入一个整数N,表示共有N组测试数据 每一组数据都是先输入该地图的行数m(0<m<100)与列数n(0<n<100),然后,输入接下来的m行每行输入n个数,表示此处有水还是没水(1表示此处是水池,0表示此处是地面)
输出描述:
输出该地图中水池的个数。 要注意,每个水池的旁边(上下左右四个位置)如果还是水池的话的话,它们可以看做是同一个水池。
样例输入:
2 3 4 1 0 0 0 0 0 1 1 1 1 1 0 5 5 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1
样例输出:
2 3
分析1(BFS):
①、该题即就是看独立的1的堆数有多少
②、根据BFS的思想,将数据为1的每层数据变为0后,向下一层遍历,以递推的思想将每一个1都变为0
步骤:
①、用BFS遍历模板完成数据1的遍历及修改
核心代码:
1 void bfs(int x, int y) 2 { 3 queue<node> Q; 4 node q1, q2; 5 q1.a = x, q1.b = y; 6 Q.push(q1); 7 while(!Q.empty()) 8 { 9 q1 = Q.front(); 10 for(int i = 0; i <= 3; ++ i) 11 { 12 q2.a = q1.a + mov[i][0]; 13 q2.b = q2.b + mov[i][1]; 14 if(!my_map[q2.a][q2.b]) continue; 15 my_map[q2.a][q2.b] = 0; 16 Q.push(q2); 17 } 18 Q.pop(); 19 } 20 }
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 const int MAXN = 105; 12 int my_map[MAXN][MAXN], book[MAXN][MAXN], mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; 13 struct node 14 { 15 int a, b; 16 }; 17 18 bool judge(node q) 19 { 20 if(my_map[q.a][q.b]) return true; 21 return false; 22 } 23 24 void bfs(int x, int y) 25 { 26 queue <node> Q; 27 node q1, q2; 28 q1.a = x, q1.b = y; 29 Q.push(q1); 30 while(!Q.empty()) 31 { 32 q1 = Q.front(); 33 for(int i = 0; i <= 3; ++ i) 34 { 35 q2.a = q1.a + mov[i][0]; 36 q2.b = q1.b + mov[i][1]; 37 if(!judge(q2)) continue; 38 my_map[q2.a][q2.b] = 0; 39 Q.push(q2); 40 } 41 Q.pop(); 42 } 43 } 44 45 int main() 46 { 47 int t; 48 scanf("%d", &t); 49 while(t --) 50 { 51 int n, m, cnt = 0; 52 memset(book, 0, sizeof(book)); 53 scanf("%d%d", &n, &m); 54 for(int i = 1; i <= n; ++ i) 55 for(int j = 1; j <= m; ++ j) 56 scanf("%d", &my_map[i][j]); 57 58 for(int i = 1; i <= n; ++ i) 59 { 60 for(int j = 1; j <= m; ++ j) 61 { 62 if(my_map[i][j]) 63 { 64 ++ cnt; 65 bfs(i, j); 66 } 67 } 68 } 69 printf("%d\n", cnt); 70 } 71 return 0; 72 }
分析2(DFS):
用DFS只是在处理遍历方式有点不同,dfs是属于一条路走到底的走法
核心代码:
1 void dfs(int x, int y) 2 { 3 if(!my_map[x+mov[i][0]][y+mov[i][1]]) return ; 4 for(int i = 0; i <= 3; ++ i) 5 { 6 if(book[x+mov[i][0]][y+mov[i][1]]) continue; 7 book[x+mov[i][0]][y+mov[i][1]] = 1; 8 my_map[x+mov[i][0]][y+mov[i][1]] = 0; 9 dfs(x+mov[i][0], y+mov[i][1]); 10 book[x+mov[i][0]][y+mov[i][1]] = 0; 11 } 12 }
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 const int MAXN = 105; 12 int my_map[MAXN][MAXN], book[MAXN][MAXN], mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; 13 struct node 14 { 15 int a, b; 16 }; 17 18 bool judge(node q) 19 { 20 if(my_map[q.a][q.b]) return true; 21 return false; 22 } 23 24 void dfs(int x, int y) 25 { 26 if(!my_map[x][y]) return; 27 for(int i = 0; i <= 3; ++ i) 28 { 29 if(book[x+mov[i][0]][y+mov[i][1]]) continue; 30 book[x+mov[i][0]][y+mov[i][1]] = 1; 31 my_map[x][y] = 0; 32 dfs(x+mov[i][0], y+mov[i][1]); 33 book[x+mov[i][0]][y+mov[i][1]] = 0; 34 } 35 } 36 37 int main() 38 { 39 int t; 40 scanf("%d", &t); 41 while(t --) 42 { 43 int n, m, cnt = 0; 44 memset(book, 0, sizeof(book)); 45 scanf("%d%d", &n, &m); 46 for(int i = 1; i <= n; ++ i) 47 for(int j = 1; j <= m; ++ j) 48 scanf("%d", &my_map[i][j]); 49 50 for(int i = 1; i <= n; ++ i) 51 { 52 for(int j = 1; j <= m; ++ j) 53 { 54 if(my_map[i][j]) 55 { 56 ++ cnt; 57 dfs(i, j); 58 } 59 } 60 } 61 printf("%d\n", cnt); 62 } 63 return 0; 64 }