AOJ 0118 Property Distribution

题目链接:https://onlinejudge.u-aizu.ac.jp/challenges/search/titles/0118

给定一张图,给定三个物品@表示苹果,#表示牡蛎,*表示橙子(直接翻译)

要求找四周联通的连通块,比如:

、在下面的 3 × 10 部分中('li' 代表苹果,'ka' 代表牡蛎,'mi' 代表橘子)

 

如果你用同一棵树擦除地块之间的边界,你会得到:

 

最终会被分成10个车厢,也就是10个人。(来自于题面)

大体思路:

进行dfs搜索,如果当前坐标满足联通条件,那就构成一个连通块;

参考代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char mp[110][110];
 4 int h,w;
 5 int ans;
 6 int dir[4][2]=
 7 {
 8     {-1,0},
 9     {0,-1},
10     {1,0},
11     {0,1},
12 };
13 bool check(int tx,int ty)
14 {
15     if(tx<0||tx>=h||ty<0||ty>=w)
16     {
17         return false;
18     }
19     return true;
20 }
21 char tmp;
22 bool vis[110][110];
23 bool dfs(int tx,int ty)
24 {
25     if(!check(tx,ty)||mp[tx][ty]!=tmp||vis[tx][ty])
26     {
27         return false;
28     }
29     vis[tx][ty]=true;//标记数组
30     for(register int i=0;i<4;i++)
31     {
32         int nex=tx+dir[i][0];
33         int ney=ty+dir[i][1];
34         dfs(nex,ney);//进行新一轮搜索
35     }
36     
37     return true;
38 }
39 int main()
40 {
41     while(scanf("%d%d",&h,&w))
42     {
43         if(h==0&&w==0)
44         break;
45         ans=0;
46         memset(vis,false,sizeof(vis));
47         for(register int i=0;i<h;i++)
48         {
49             for(register int j=0;j<w;j++)
50             {
51                 cin>>mp[i][j];
52             }
53         }
54         for(register int i=0;i<h;i++)
55         {
56             for(register int j=0;j<w;j++)
57             {
58                 tmp=mp[i][j];//用以判断和当前图符是否一样
59                 if(dfs(i,j))//从头开始搜索
60                 {
61                     ans++;
62                 }
63             }
64         }
65         cout<<ans<<endl;
66     }
67     return 0;
68 }

 

总结:

1.如何判断连通块?dfs

2.临时变量的应用:

 1 tmp=mp[i][j];//用以判断和当前图符是否一样 

 

posted @ 2022-07-04 21:07  江上舟摇  阅读(30)  评论(0编辑  收藏  举报