题意:给一个矩阵,数字相同且挨着的视为联通区域,给定x,y,求所在的联通块的周长
思路:Bfs求出联通块的个数,每次搜索的时候判断四周是否是联通的,如果是联通,说明有一条边是重合的,最后联通块的个数*4-重合的边就是答案了(每2个联通的格子之间重合的边回计算2次,但因为重合的2条边都不会计算入周长,所以不用去重才是答案)
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) #define mp(x,y) make_pair(x,y) using namespace std; const long long INF = 1e18+1LL; const int inf = 2e9+1e8; const int N=1e5+100; const ll mod=1e9+7; struct Node{ int xx,yy; }; int dis[4][2]{{0,1},{0,-1},{-1,0},{1,0}}; int n,m,x,y,ans=1,r,g[105][105]; void Bfs(int x,int y){ queue<Node> Q; while(!Q.empty()) Q.pop(); int vis[105][105]; mem(vis); Node now,next; now.xx=x,now.yy=y; Q.push(now); vis[x][y]=1; while(!Q.empty()){ now=Q.front(); Q.pop(); for(int i=0; i<4; ++i){ next.xx=now.xx+dis[i][0]; next.yy=now.yy+dis[i][1]; if(g[next.xx][next.yy]==g[now.xx][now.yy]){ r++; if(!vis[next.xx][next.yy]){ Q.push(next); vis[next.xx][next.yy]=1; ans++; } } } } } int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); memset(g,-1,sizeof(g)); cin>>n>>m>>x>>y; for(int i=1; i<=n; ++i){ for(int j=1; j<=m; ++j){ cin>>g[i][j]; } } Bfs(x+1,y+1); cout<<ans*4-r<<endl; return 0; }