Sicily 1428. B Baby Climber(心宝去爬山)
【原题】
Description
心宝热爱运动,喜欢爬山。一天他去道场山游玩。杭嘉湖平原多丘陵,心宝手上有一幅地图,是分层设色地形图(地图为长宽均不超过50的矩阵),心宝想算算地图上有多少个山顶他需要翻越。 请你计算一下,心宝所给的地图中有几个山顶 Input
输入输出包括多个Case。 每个Case包含多行,每一行包含相等数量的小写字母,表示地图的每一行内容。 每个Case以*****表示结束。 数据间没有多余的空格和空行。 输入保证每个Case最多不超过50行,每行不超过50个字符。 Output
每个Case一行输出山顶数目 Sample Input
ccccc cbbbc cbabc cbbbc ccccc ***** cbbcbabc cbbcbabc cbbcbabc cbbcbabc ***** Sample Output
1 2 Problem Source: ,Renaissance |
【思路】
用宽搜做,对每一个点进行操作:如果该点还没访问过,那么上下左右哪个点跟它相等,就把它放到一个队列里面,然后标记为访问过,貌似这个操作叫‘flood fill’还是什么,对“这一片”进行判断,如果边缘没有比它“高”的地方,那么它就是山顶,山顶数目加1;否则“这一片”就作废了,下次不用再访问到这一片,山顶数目不变。
1 #include <stdio.h> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 struct node 7 { 8 char c; 9 int x,y; 10 node(int x1,int y1,char c1) 11 { 12 x=x1; 13 y=y1; 14 c=c1; 15 } 16 }; 17 18 string hill[51]; 19 int xchg[]={-1,0,1,0}; 20 int ychg[]={0,1,0,-1}; 21 int vis[51][51]; 22 int top=0; 23 bool out(int x,int y,int x1,int y1) //是否出界了 24 { 25 if(x1<0 || x1>=x || y1<0 || y1>=y) 26 return true; 27 else 28 return false; 29 } 30 void bfs(int row,int col,int x,int y,char c) //宽搜 31 { 32 if(vis[x][y]==1) //访问过了就不搜了 33 return; 34 vis[x][y]=1; 35 queue<node> q; 36 q.push(node(x,y,c)); 37 bool bb=1; 38 while(!q.empty()) 39 { 40 node t=q.front(); 41 q.pop(); 42 int xx,yy; 43 for(int i=0;i<4;i++) //搜四周的点 44 { 45 xx=t.x+xchg[i]; 46 yy=t.y+ychg[i]; 47 if(out(row,col,xx,yy))continue; 48 49 if(hill[xx][yy]<t.c) 50 { 51 bb=0; 52 continue; 53 } 54 if(vis[xx][yy]==0) 55 { 56 if(hill[xx][yy]==t.c) 57 { 58 q.push(node(xx,yy,t.c)); 59 vis[xx][yy]=1; 60 } 61 } 62 } 63 } 64 if(bb==0)return; 65 else 66 top++; 67 } 68 69 int main() 70 { 71 72 string t; 73 while(cin>>t) 74 { 75 hill[0]=t; 76 int a=1; 77 top=0; 78 while(cin>>t) 79 { 80 if(t=="*****") 81 break; 82 else 83 hill[a++]=t; 84 } 85 int x=a,y=hill[0].size(); 86 memset(vis,0,sizeof(vis)); 87 vis[x][y]=1; 88 for(int i=0;i<x;i++) //搜每一个点 89 for(int j=0;j<y;j++) 90 bfs(x,y,i,j,hill[i][j]); 91 92 cout<<top<<endl; 93 } 94 }