题目:
思路:
我们可以用广搜找出每一个房间的面积和房间数,然后枚举每一个墙的拆掉的最大值和坐标。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int x,n,m,wall[51][51][5],mj[51],fh[51][51],fj,tail,head,state[2501][3],maxans,ansx,ansy;
char answ;
short dx[4]={1,-1,0,0},dy[4]={0,0,-1,1};
bool check(int x,int y,int xx,int yy)
{
if (xx<1||xx>n||yy<1||yy>m) return false;
if (xx-1==x&&yy==y&&!wall[xx][yy][1]) return true;
if (xx+1==x&&yy==y&&!wall[xx][yy][2]) return true;
if (xx==x&&yy-1==y&&!wall[xx][yy][3]) return true;
if (xx==x&&yy+1==y&&!wall[xx][yy][4]) return true;
return false;
}
void bfs(int x,int y)
{
if (fh[x][y]>0) return;//fh代表(i,j)所属的房间号,如果这里有值就代表搜过了,就不用搜了
tail=1;head=0;fj++;//fj代表这是第几个房间号
fh[x][y]=fj;
state[1][1]=x;
state[1][2]=y;//赋初值
int xx,yy;
do
{
head++;
for (int i=0;i<=3;i++)
{
xx=state[head][1]+dx[i];yy=state[head][2]+dy[i];
if (check(state[head][1],state[head][2],xx,yy)&&!fh[xx][yy])//判断当前这个点能否到新坐标,而且新坐标没有被统计过
{
tail++;
state[tail][1]=xx;
state[tail][2]=yy;
fh[xx][yy]=fj;
}
}
}while (head<tail);
}
int main()
{
scanf("%d%d",&m,&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
scanf("%d",&x);//因为读入的是1,2,4,8的和,所以我们这样做
if (x>=8){x-=8;wall[i][j][2]=1;}//1,2,3,4分别代表北南东西墙,wall[i][j][]是代表这个坐标的北南东西有没有墙
if (x>=4){x-=4;wall[i][j][4]=1;}
if (x>=2){x-=2;wall[i][j][1]=1;}
if (x>=1){x-=1;wall[i][j][3]=1;}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
bfs(i,j);//广搜出面积和房间号
mj[fj]=tail;
maxans=max(maxans,tail);//统计最大的面积
}
printf("%d\n%d\n",fj,maxans);
maxans=0;ansy=2100000000;ansx=-1;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)//这里是求拆墙的最优解
{
if (fh[i][j]!=fh[i][j-1])//如果它西边的房间和它不是一个的,而且
if(mj[fh[i][j]]+mj[fh[i][j-1]]>maxans||//把这墙拆掉比最优解大的,或者
(mj[fh[i][j]]+mj[fh[i][j-1]]==maxans&&j<ansy)||//它等于最优解,但更靠西的,或者
(mj[fh[i][j]]+mj[fh[i][j-1]]==maxans&&j-1==ansy&&i>ansx))//它和上一个答案一样西,但是更靠南
{maxans=mj[fh[i][j]]+mj[fh[i][j-1]];ansx=i;ansy=j-1;answ='E';}//存下最优解,因为我们是东边求过来的,所以j要-1
if (fh[i][j]!=fh[i-1][j])//这里和上面差不多
if(mj[fh[i][j]]+mj[fh[i-1][j]]>maxans||
(mj[fh[i][j]]+mj[fh[i-1][j]]==maxans&&j<ansy)||
(mj[fh[i][j]]+mj[fh[i-1][j]]==maxans&&j==ansy&&i>ansx))
{maxans=mj[fh[i][j]]+mj[fh[i-1][j]];ansx=i;ansy=j;answ='N';}//存下最优解
}
printf("%d\n%d %d %c",maxans,ansx,ansy,answ);
}
本文介绍了一种使用广度优先搜索解决洛谷1457问题的方法,通过计算每个房间的最大面积及拆除墙壁后的最大价值。代码实现详细展示了如何遍历地图并更新房间编号,最终找到最优解。
862

被折叠的 条评论
为什么被折叠?



