题目大意:
给出一副N*M的图,图上的任意一点[i,j]中四周可能存在墙壁,用ai,j描述周围的墙壁,
每个ai,j表示[i,j]东西南北是否有墙存在。每个数字是由以下四个整数的某个或某几个或一个都没。
1: 在西面有墙
2: 在北面有墙
4: 在东面有墙
8: 在南面有墙
求①城堡的房间数目②最大的房间的大小
③移除一面墙能得到的最大的房间的大小
④移除哪面墙可以得到面积最大的新房间。
选择最佳的墙来推倒。有多解时选最靠西的,仍然有多解时选最靠南的。同一格子北边的墙比东边的墙更优先。
用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位(”N”(北)或者”E”(东))。
题解:
①仔细读题可知,
每个ai,j描述的是四周的墙壁的情况
墙壁并不存在坐标i,j,只是用于隔绝
②对图进行染色,找出房子数跟最大房子大小,dfs即可
时间复杂度:O(NM)
③考虑合并的最大值,
枚举每个坐标[i,j],判断一个向北推翻的最大合并值,一个向东的
④判断输出即可
这题好辣鸡、、一个细节我纠结了那么久
代码:
#include<bits/stdc++.h>
#define N 55
using namespace std;
const int dx[]={0,-1,0,1};
const int dy[]={-1,0,1,0};
int n,m,a[N][N],cnt[N][N],area[N*N],tot=0;
bool check(int x,int y) {
if (x<1 || x>n || y<1 || y>m || cnt[x][y]) return 0;
return 1;
}
void dfs(int x,int y,int z) {
cnt[x][y]=z;
area[z]++;
for (int i=0; i<=3; i++)
if (!( a[x][y] & (1<<i) )) {
int x1=x+dx[i],y1=y+dy[i];
if (check(x1,y1)) dfs(x1,y1,z);
}
}
int main() {
scanf("%d%d",&m,&n);
for (int i=1; i<=n; i++)
for(int j=1; j<=m; j++) scanf("%d",&a[i][j]);
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
if (!cnt[i][j])
{
tot++;
dfs(i,j,tot);
}
int cmax=0;
for (int i=1; i<=tot; i++)
cmax=max(cmax,area[i]);
printf("%d\n%d\n",tot,cmax);
int ans1=cmax,ans2=cmax;
int cp=0,x1=0,y1=0,x2=0,y2=0;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++) {
if ( (a[i][j]&2) && (cnt[i][j]!=cnt[i-1][j]) ){
cp=area[cnt[i][j]]+area[cnt[i-1][j]];
if (ans1<cp) { ans1=cp; x1=i; y1=j; }
else if (ans1==cp){ //就是这个辣鸡=号,我只打了一个一开始。。
if (j<y1) { x1=i; y1=j;}
else if (j==y1) x1=i;
}
}
if ( (a[i][j]&4) && (cnt[i][j]!=cnt[i][j+1]) ){
cp=area[cnt[i][j]]+area[cnt[i][j+1]];
if (ans2<cp) { ans2=cp; x2=i; y2=j; }
else if (ans2==cp){ //还有这个
if (j<y2) { x2=i; y2=j;}
else if (j==y2) x2=i;
}
}
}
printf("%d\n",max(ans1,ans2));
if (ans1>ans2) printf("%d %d N\n",x1,y1);
if (ans1<ans2) printf("%d %d E\n",x2,y2);
if (ans1==ans2){
if (y1<y2) printf("%d %d N\n",x1,y1);
else if (y1>y2) printf("%d %d E\n",x2,y2);
else if (x1>x2) printf("%d %d N\n",x1,y1);
else if (x1<x2) printf("%d %d E\n",x2,y2);
else printf("%d %d N\n",x1,y1);
}
return 0;
}