wall[i][j][4]用来存(i,j)这个位置周围四面墙的情况,ans用来记房间的数量。如果(i,j)包含在第k个大房间,则f[i][j]=k,这样以后可以很方便的比较f[][]的值判断是否在一个大房间。c[]用来表示第ans个大房间的小房间数,然后dfs分别求包含小房间(i,j)的大房间包含的的小房间数,记录最大值。最后遍历每一个小房子,通过拆除其周围的某一面墙获得大房间,记下取得最大房间大小的最大值和取得此值时的(i,j)的位置和墙的方位。
/*
ID:jzzlee1
PROG:castle
LANG:C++
Dear double_tings:
i love you.
*/
#include<iostream>
#include<fstream>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
using namespace std;
int graph[105][105]={0};
bool wall[105][105][4]={0}; //0代表无墙,1有墙 //第三维:0西面,1北面,2东面 3南面
int f[105][105]={0}; //记录各个连通分量 (第ans个)
int c[6000]={0}; //第ans个连通分量房间的数目
ifstream fin("castle.in");
ofstream fout("castle.out");
int n,m,ans; //ans表示房间数
void dfs(int i,int j,int &count)//深度优先遍历求最大包含小房间(i,j)的大房间包含的的小房间数
{ //对于每个包含(i,j)的大房间,只需dfs一次就可求出count
if(i<1||i>m||j<1||j>n||graph[i][j])
return;
f[i][j]=ans;
graph[i][j]=++count;
if(!wall[i][j][0])dfs(i,j-1,count);
if(!wall[i][j][1])dfs(i-1,j,count);
if(!wall[i][j][2])dfs(i,j+1,count);
if(!wall[i][j][3])dfs(i+1,j,count);
}
int main()
{
fin>>n>>m;
//cin>>n>>m;
int temp;
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
{
fin>>temp;
//cin>>temp;
if(temp&1)wall[i][j][0]=1;
if(temp&2)wall[i][j][1]=1;
if(temp&4)wall[i][j][2]=1;
if(temp&8)wall[i][j][3]=1;
}
ans=0;
int max=0;
for(int i=1; i <= m; i++ )
for(int j=1; j <= n ; j++)
{
if(!graph[i][j])
{
int count=0;
ans++;
dfs(i,j,count);
if(count>max)
max=count;
c[ans]=count;
}
}
fout<<ans<<endl;
fout<<max<<endl;
//cout<<ans<<endl;
//cout<<max<<endl;
int ii,jj,mmax=0;char ch;
for(int j=1; j<=n; j++)
for(int i=m; i>=1; i--) //由下而上从左到右遍历每个小房间
{ //求拆一面墙得到的最大房间大小
if(wall[i][j][1]&&f[i][j]!=f[i-1][j]&&c[f[i][j]]+c[f[i-1][j]]>mmax)
{
mmax=c[f[i][j]]+c[f[i-1][j]];
ii=i;
jj=j;
ch='N';
}
if(wall[i][j][2]&&f[i][j]!=f[i][j+1]&&c[f[i][j]]+c[f[i][j+1]]>mmax)
{
mmax=c[f[i][j]]+c[f[i][j+1]];
ii=i;
jj=j;
ch='E';
}
}
fout<<mmax<<endl;
fout<<ii<<" "<<jj<<" "<<ch<<endl;
//cout<<mmax<<endl;
//cout<<ii<<' '<<jj<<' '<<ch<<endl;
return 0;
}