1 条题解
-
0
C++ :
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const ll Inf=0x3f3f3f3f3f3f3f3f; int n,m; int a[55][55][4]; //记录四个方向是否有墙 int order[55][55]; //记录这个点属于那个连通块 int s; //连通块的编号 int f[2899]; //f[i]表示编号为i的连通块里有多少元素 bool vis[55][55]; //bfs标记这个点是否被访问过 int maxn; //记录最大连通块元素数量 int sum; //连通块个数 int num; //某狗连通块内元素个数 int res; //拆掉一堵墙后最大连通块元素数量 int ans1,ans2; //拆掉的墙所属位置 char op; //E还是N墙 struct node{ int x; int y; }; queue<node>q; void bfs(){ //一次bfs找一个连通块 s++; int nxt[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; int i; num=0; while(!q.empty()){ node cur=q.front(); q.pop(); num++; //本连通块元素数量 order[cur.x][cur.y]=s; //每次bfs把这次bfs所访问到的的点打上所属连通块的标记 for(i=0;i<4;i++){ int tx=cur.x+nxt[i][0]; int ty=cur.y+nxt[i][1]; if(tx<1||ty<1||tx>n||ty>m)continue; if(!vis[tx][ty]&&a[cur.x][cur.y][i]==0){ vis[tx][ty]=1; q.push(node{tx,ty}); } } } f[s]=num; //把此次bfs找到的连通块的元素数量记为num,所有属于这个连通块的元素都可以用 maxn=max(maxn,num); return ; } int main (){ ios::sync_with_stdio(false); cin.tie(0); cin>>m>>n; int i,j,k; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ int x; cin>>x; if((x&1)==1)a[i][j][0]=1;//位运算 1 2 4 8都是2的次幂,二进制分别0001 0010 0100 1000 if((x&2)==2)a[i][j][1]=1;//注意位运算的优先级,==优先级大于& if((x&4)==4)a[i][j][2]=1; if((x&8)==8)a[i][j][3]=1; } } for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(!vis[i][j]){ //bfs找连通块 q.push(node{i,j}); vis[i][j]=1; sum++; bfs(); } } } //cout<<sum<<" "<<maxn<<endl; for(j=1;j<=m;j++){ //从西到东,从南到北 for(i=n;i>=1;i--){ //北墙优先,东墙次之 for(k=1;k<=2;k++){ if(k==1){ if(i==1)continue; if(a[i][j][1]==1&&order[i][j]!=order[i-1][j]){ //注意,条件是两元素间有墙且属于不同连通块 int tmp=f[order[i][j]]+f[order[i-1][j]]; if(tmp>res){ res=tmp; ans1=i; ans2=j; op='N'; } } }else if(k==2){ if(j==m)continue; if(a[i][j][2]==1&&order[i][j]!=order[i][j+1]){ int tmp=f[order[i][j]]+f[order[i][j+1]]; if(tmp>res){ res=tmp; ans1=i; ans2=j; op='E'; } } } } } } cout<<sum<<endl; cout<<maxn<<endl; cout<<res<<endl; cout<<ans1<<" "<<ans2<<" "<<op<<endl; return 0; }
- 1
信息
- ID
- 1440
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者