题目
输入城堡的长和宽,然后长*宽个数据表示每个单元墙的情况,1西2北4东8南,0-15就可以表示任何一种围墙的情况。要求计算房间数,最大房间面积,凿掉某一堵墙后可能形成的最大房间面积以及这种情况下所凿的墙。
题目细节
数据都是没问题的,凿的墙用某房间的东或者北来表示,优先最西边的,再优先最南边的。
题解
首先处理墙的情况,具体操作就是判断是否大于8,大于就表示南边有墙,然后减去8,以此类推。
然后是广搜,使用一个房间号,广搜的时候把该起点所在房间的每一个单元都标上这个房间号,广搜结束后求得的是起点所在房间的面积,把所有标有这个数的单元,即这个起点所处房间的每个单元的面积都填上。然后到下一个没跑过的单元,以其为起点,再广搜。全部结束后已经可以得到最大房间的面积了。然后对每一个单元,计算它所在房间的面积,再加上它东或者北单元所在房间的面积(房间号要不同),就可以得到两个房间最大的面积和具体的哪一堵墙。
代码
/*
ID: xcwhkh1
LANG: C++
TASK: castle
*/
#include <stdio.h>
struct rm
{
int wall[4];//0南,1东,2北,3西
int f,s,ss,ff,zu;
};
rm room[52][52];
int r[52][52];
int roomnum=0;
void bfs(int a,int b)
{
room[a][b].f=1;
room[a][b].ff=1;
if(room[a][b].wall[0]==0&&room[a+1][b].f==0)
{
room[a+1][b].zu=room[a][b].zu;
bfs(a+1,b);
room[a][b].s+=room[a+1][b].s;
}
if(room[a][b].wall[1]==0&&room[a][b+1].f==0)
{
room[a][b+1].zu=room[a][b].zu;
bfs(a,b+1);
room[a][b].s+=room[a][b+1].s;
}
if(room[a][b].wall[2]==0&&room[a-1][b].f==0)
{
room[a-1][b].zu=room[a][b].zu;
bfs(a-1,b);
room[a][b].s+=room[a-1][b].s;
}
if(room[a][b].wall[3]==0&&room[a][b-1].f==0)
{
room[a][b-1].zu=room[a][b].zu;
bfs(a,b-1);
room[a][b].s+=room[a][b-1].s;
}
}
int main(){
FILE *fin=fopen("castle.in","r");
FILE *fout=fopen("castle.out","w");
int l,w,rt=0,t,max;
fscanf(fin,"%d%d",&l,&w);//长宽
for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)
{
fscanf(fin,"%d",&rt);
for(int k=0;k<4;k++)
room[i][j].wall[k]=0;
t=0;
for(int k=8;k>0;k/=2)
{
if(rt>=k)
{
room[i][j].wall[t]=1;
rt-=k;
}
t++;
}
}
//bfs
for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)
{
if(room[i][j].ff==0)
{
roomnum++;
room[i][j].zu=roomnum;
for(int ii=1;ii<=w;ii++)
for(int jj=1;jj<=l;jj++)
{
room[ii][jj].s=1;
room[ii][jj].f=0;
}
bfs(i,j);
room[i][j].ss=room[i][j].s;
if(room[i][j].s>max)
max=room[i][j].s;
}
}
for(int i=1;i<=w;i++)
for(int j=1;j<=l;j++)
if(room[i][j].zu)
for(int ii=1;ii<=w;ii++)
for(int jj=1;jj<=l;jj++)
if(room[ii][jj].zu==room[i][j].zu&&room[ii][jj].ss)
room[i][j].s=room[ii][jj].ss;
int maxs=0;
int x,y;
char push;
if(l==1)
{
for(int i=w;i>1;i--)
if(room[i][1].s+room[i-1][1].s>maxs&&room[i][1].zu!=room[i-1][1].zu)
{
maxs=room[i][1].s+room[i-1][1].s;
x=1;
y=i;
push='N';
}
}
else if(w==1)
{
for(int j=1;j<l;j++)
if(room[1][j].s+room[1][j+1].s>maxs&&room[1][j].zu!=room[1][j+1].zu)
{
maxs=room[1][j].s+room[1][j+1].s;
x=j;
y=1;
push='E';
}
}
else
{
for(int j=1;j<=l;j++)
for(int i=w;i>=1;i--)
{
if(i!=1&&room[i][j].s+room[i-1][j].s>maxs&&room[i][j].zu!=room[i-1][j].zu)
{
maxs=room[i][j].s+room[i-1][j].s;
x=i;
y=j;
push='N';
}
if(j!=l&&room[i][j].s+room[i][j+1].s>maxs&&room[i][j].zu!=room[i][j+1].zu)
{
maxs=room[i][j].s+room[i][j+1].s;
x=i;
y=j;
push='E';
}
}
}
// for(int i=1;i<=w;i++)
// {
// for(int j=1;j<=l;j++)
// printf("%d ",room[i][j].s);
// printf("\n");
// }
fprintf(fout,"%d\n%d\n%d\n%d %d %c\n",roomnum,max,maxs,x,y,push);
return 0;
}
本文介绍了一种通过广度优先搜索解决迷宫问题的方法,详细解释了如何将迷宫问题转化为计算房间数量、最大房间面积及可能的最大合并面积等问题,并提供了完整的C++实现代码。
386

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



