傻卵DFS吧,然而WA了两发我也是醉。English渣到爆, farthest to the west是最西面而不是离西面最远,嗯。
题意,给一个n*m的地图,把数字写成2进制,共4位,每一位代表一个方向是否有墙。问房间数,最大房间的size,去掉一面墙后合并的两个房间的最大size,要求去掉的墙最西最南,方向先N后E。
做法:dfs一遍,给每个房间编号,记录每个房间的size,得出房间数和最大size。按照优先级跑一遍,每次判断位置上是否有墙,墙两边是否房间不同,两房间之和是否大于当前最大值,均正确后更新。
代码:
/*
ID: jlw44671
PROG: castle
LANG: C++
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
int pic[55][55];
bool vis[55][55];
int m,n;
int tag[55][55];
int size[55*55];
int M,M2,tagpos;
bool flag;
int recx,recy;
void dfs(int x,int y)
{
vis[x][y]=true;
tag[x][y]=tagpos;
size[tagpos]++;
if(!(pic[x][y]&1)&&!vis[x][y-1])dfs(x,y-1);
if(!(pic[x][y]&2)&&!vis[x-1][y])dfs(x-1,y);
if(!(pic[x][y]&4)&&!vis[x][y+1])dfs(x,y+1);
if(!(pic[x][y]&8)&&!vis[x+1][y])dfs(x+1,y);
return;
}
int main()
{
freopen("castle.in","r",stdin);
freopen("castle.out","w",stdout);
memset(vis,false,sizeof(vis));
scanf("%d %d",&m,&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
scanf("%d",&pic[i][j]);
}
M=0;
tagpos=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!vis[i][j]){tagpos++;dfs(i,j);}
}
}
for(int i=1;i<=tagpos;i++)
M=max(M,size[i]);
M2=0;
printf("%d\n%d\n",tagpos,M);
for(int j=1;j<=m;j++)
for(int i=n;i>=1;i--)
{
if(i!=1&&(pic[i][j]&2)&&(tag[i][j]!=tag[i-1][j])&&(M2<size[tag[i][j]]+size[tag[i-1][j]]))
{
flag=true;
recx=i;
recy=j;
M2=size[tag[i][j]]+size[tag[i-1][j]];
}
if(j!=m&&(pic[i][j]&4)&&(tag[i][j]!=tag[i][j+1])&&(M2<size[tag[i][j]]+size[tag[i][j+1]]))
{
flag=false;
recx=i;
recy=j;
M2=size[tag[i][j]]+size[tag[i][j+1]];
}
}
printf("%d\n%d %d %c\n",M2,recx,recy,flag==true?'N':'E');
return 0;
}