两个题是一个题~~只不过POJ的更弱些,只要找到房间数以及最大房间的面积就ok了...
首先是构造墙~~我是用个4位的bool数组来记录每个点的墙的情况...读入时就%2.再/2...就可以构造出来~~
找房间数和最大房间直接DFS就可以了~~边遍历边标记~~每个点标记成所在的区域~~在递归的过程中很好实现~
而找去掉一面墙以及去掉一面墙最大面积~~就按所要求的优先顺序枚举墙~~判断下两边是否为一个房间~~并且两边的和是否是最大的~~~
Program:
/*
ID: zzyzzy12
LANG: C++
TASK: castle
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
bool s[4];
int data;
}mar[55][55];
int n,m,i,j,k,t,Size[3001],MaxSize,RoomNum,ans,x,y;
char f;
void search(int y,int x)
{
if (mar[y][x].data) return;
Size[RoomNum]++;
mar[y][x].data=RoomNum;
if (!mar[y][x].s[0]) search(y,x-1);
if (!mar[y][x].s[1]) search(y-1,x);
if (!mar[y][x].s[2]) search(y,x+1);
if (!mar[y][x].s[3]) search(y+1,x);
}
int main()
{
freopen("castle.in","r",stdin);
freopen("castle.out","w",stdout);
scanf("%d%d",&m,&n);
memset(mar,0,sizeof(mar));
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
scanf("%d",&k);
t=0;
while (k)
{
if (k%2) mar[i][j].s[t]=true;
k/=2;
t++;
}
}
MaxSize=RoomNum=0;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (!mar[i][j].data)
{
RoomNum++;
Size[RoomNum]=0;
search(i,j);
if (Size[RoomNum]>MaxSize) MaxSize=Size[RoomNum];
}
printf("%d\n%d\n",RoomNum,MaxSize);
ans=0;
for (j=1;j<=m;j++)
for (i=n;i>=1;i--)
{
if (mar[i][j].s[0] && j!=1 && mar[i][j].data!=mar[i][j-1].data && ans<Size[mar[i][j].data]+Size[mar[i][j-1].data])
{
y=i; x=j; f='W'; ans=Size[mar[i][j].data]+Size[mar[i][j-1].data];
}
if (mar[i][j].s[1] && i!=1 && mar[i][j].data!=mar[i-1][j].data && ans<Size[mar[i][j].data]+Size[mar[i-1][j].data])
{
y=i; x=j; f='N'; ans=Size[mar[i][j].data]+Size[mar[i-1][j].data];
}
if (mar[i][j].s[2] && j!=m && mar[i][j].data!=mar[i][j+1].data && ans<Size[mar[i][j].data]+Size[mar[i][j+1].data])
{
y=i; x=j; f='E'; ans=Size[mar[i][j].data]+Size[mar[i][j+1].data];
}
if (mar[i][j].s[3] && i!=n && mar[i][j].data!=mar[i+1][j].data && ans<Size[mar[i][j].data]+Size[mar[i+1][j].data])
{
y=i; x=j; f='S'; ans=Size[mar[i][j].data]+Size[mar[i+1][j].data];
}
}
printf("%d\n%d %d %c\n",ans,y,x,f);
return 0;
}