码迷,mamicode.com
首页 > 其他好文 > 详细

nyoj27-水池数目 (求连通块数目)【dfs】

时间:2015-06-17 23:03:17      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.nyist.net/JudgeOnline/problem.php?pid=27

水池数目

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
 
描述
南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水池。
 
输入
第一行输入一个整数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组成的连通块的数目。

题解1:dfs

 1 #include <fstream>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N=100;
 9 int m,n,ans;
10 int a[N][N];
11 bool b[N][N];
12 int xy[2][4]={{1,-1,0,0},{0,0,1,-1}};
13 
14 bool check(int x,int y);
15 void dfs(int x,int y);
16 
17 int main()
18 {
19     //freopen("D:\\input.in","r",stdin);
20     //freopen("D:\\output.out","w",stdout);
21     int T;
22     scanf("%d",&T);
23     while(T--){
24         ans=0;
25         scanf("%d%d",&m,&n);
26         for(int i=0;i<m;i++)
27             for(int j=0;j<n;j++)
28                 scanf("%d",&a[i][j]);
29         memset(b,0,sizeof(b));
30         for(int i=0;i<m;i++)
31             for(int j=0;j<n;j++)
32                 if((!b[i][j])&&a[i][j])    dfs(i,j),ans++;
33         printf("%d\n",ans);
34     }
35     return 0;
36 }
37 bool check(int x,int y){
38     return x>=0&&x<m&&y>=0&&y<n&&b[x][y]==0;
39 }
40 void dfs(int x,int y){
41     b[x][y]=1;
42     if(!a[x][y])    return;
43     int tx,ty;
44     for(int i=0;i<4;i++){
45         tx=x+xy[0][i];
46         ty=y+xy[1][i];
47         if(check(tx,ty))  dfs(tx,ty);
48     }
49 }

题解2:非递归方式:队列。建立队列q,遍历二维图所有点,对每个点扩展的点存入队列,再一一处理。

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int t,n,m,e=1000,i,j,k,s,num,q[10010],r[110][110];
 6     scanf("%d",&t);
 7     while(t--)
 8     {
 9         scanf("%d%d",&n,&m);
10         for(i=0;i<n;i++)
11             for(j=0;j<m;j++)
12                 scanf("%d",&r[i][j]);
13         num=0;
14         for(i=0;i<n;i++)
15             for(j=0;j<m;j++)
16             {
17                 if(r[i][j]==1)
18                 {
19                     int a,b;
20                     a=i;
21                     b=j;
22                     k=1;
23                     s=0;
24                     while(s<k)
25                     {
26                         if(r[a][b-1]==1)
27                         {
28                             q[k++]=a*e+b-1;
29                             r[a][b-1]=0;
30                         }
31                         if(r[a][b+1]==1)
32                         {
33                             q[k++]=a*e+b+1;
34                             r[a][b+1]=0;
35                         }
36                         if(r[a-1][b]==1)
37                         {
38                             q[k++]=(a-1)*e+b;
39                             r[a-1][b]=0;
40                         }
41                         if(r[a+1][b]==1)
42                         {
43                             q[k++]=(a+1)*e+b;
44                             r[a+1][b]=0;
45                         }
46                         a=q[++s]/e;
47                         b=q[s]%e;
48                     }
49                     num++;
50                 }
51             }
52         printf("%d\n",num);
53     }
54     return 0;
55 }

nyoj27-水池数目 (求连通块数目)【dfs】

标签:

原文地址:http://www.cnblogs.com/jiu0821/p/4584543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!