题目给了一个二维矩阵,矩阵的每个数字代表一个单位的面积,每个数字转换为二进制,这个四位二进制数的每一位,分别代表了自己的东南西北是否有墙。
题目求房间的数目,最大的自然房间的大小,拆掉某一堵墙之后的可能会造成某两个自然房间合并,求合成最大房间的面积,以及拆除的抢的坐标,以及位置
做法是,对单位面积进行染色,可以相互联通的区域就是一个房间。
再设一个数组Size表示染色为i的房间的大小,
然后枚举拆掉每堵墙之后的情况,合成的房间的大小就是自己和自己相邻的单位面积所代表的房间大小(Size中的值)相加
/*
ID: modengd1
PROG: castle
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
int input[52][52];
int color[52][52];
int Size[255];
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};//此处根据题意给的从左往右每位代表的墙的情况设置,提高了代码重用率,但增加了编程复杂度
//染色,C为当前所染的颜色
int dfs(int x,int y,int C)
{
int ret=1;
color[x][y]=C;
for(int i=0;i<4;i++)
{
if((input[x][y]&(1<<i))==0&&color[x+dx[i]][y+dy[i]]==0)
{
ret+=dfs(x+dx[i],y+dy[i],C);
}
}
return ret;
}
/*A墙去掉之后,和B墙去掉之后,得到的结果作比较,如果A墙去掉之后更加符合题目要求的
房子最大,最靠西,最靠南,则返回true,否则返回false, ch表示时E墙还是N墙,lar代表去掉这堵墙之后构造的房间的面积
*/
bool isAbigThanB(int i1,int j1,int ch1,int lar1,int i2,int j2,int ch2,int lar2)
{
//大小不一样,直接根据大小决定是否替换
if(lar1!=lar2)
return lar1>lar2;
//不再同一个垂直线上时,比较j
if(j1!=j2)
return j1<j2;
//在同一个水平线上时,N比E所代表的更加靠西
if(ch1!=ch2)
return ch1>ch2;
//程序执行到此说明,房间大小一样,且按照最靠西的标准无法确定,则选择最靠南的
return i1>i2;
}
int main()
{
freopen("castle.in","r",stdin);
freopen("castle.out","w",stdout);
int N,M,c;
int rooms,lar,lar2,x,y;
char ch;
memset(color,0,sizeof(color));
memset(Size,0,sizeof(Size));
scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
scanf("%d",&input[i][j]);
}
}
//lar表示最大的自然房间的大小
c=1;lar=0;
//染色
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
if(color[i][j]==0)
{
Size[c]=dfs(i,j,c);
lar=max(lar,Size[c]);
c++;
}
}
}
rooms=c-1;
lar2=0;
//lar2表示最大的合成房间的大小
//模拟去掉每堵墙
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
//假设去掉自己的北面,也就是相邻的南面
if(color[i][j]!=color[i-1][j])
{
int temp=Size[color[i][j]]+Size[color[i-1][j]];
if(isAbigThanB(i,j,'N',temp,x,y,ch,lar2))
{
x=i;y=j;
lar2=temp;
ch='N';
}
}
//假设去掉自己的东面,也就是相邻的西部
if(color[i][j]!=color[i][j+1])
{
int temp=Size[color[i][j]]+Size[color[i][j+1]];
if(isAbigThanB(i,j,'E',temp,x,y,ch,lar2))
{
x=i;y=j;lar2=temp;
ch='E';
}
}
}
}
cout<<rooms<<endl;
cout<<lar<<endl;
cout<<lar2<<endl;
cout<<x<<' '<<y<<' '<<ch<<endl;
return 0;
}