题目
166:The Castle
总时间限制: 1000ms 内存限制: 65536kB
描述
Figure 1 shows the map of a castle.Write a program that calculates
- how many rooms the castle has
- how big the largest room is
The castle is divided into m * n (m<=50, n<=50) square modules. Each such module can have between zero and four walls.
输入
Your program is to read from standard input. The first line contains the number of modules in the north-south direction and the number of modules in the east-west direction. In the following lines each module is described by a number (0 <= p <= 15). This number is the sum of: 1 (= wall to the west), 2 (= wall to the north), 4 (= wall to the east), 8 (= wall to the south). Inner walls are defined twice; a wall to the south in module 1,1 is also indicated as a wall to the north in module 2,1. The castle always has at least two rooms.
输出
Your program is to write to standard output: First the number of rooms, then the area of the largest room (counted in modules).
样例输入
4
7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13
样例输出
5
9
翻译
图Figure1显示shows了一个城堡的地图。写一个计算calculates程序
- 城堡有多少个房间
- 最大的房间有多大啊
城堡被划分为m * n (m<=50, n<=50)个正方形square单元modules。每个这样的模块可以有零到四面墙。
输入
您的程序将从标准输入中读取数据。
第一行包含南北方向的模块数和东西方向的模块数。
在接下来的几行中,每个模块用一个数字(0 <= p <= 15)来描述。
这个数字是以下数的总和:1(=西面的墙),2(=北面的墙),4(=东面的墙),8(=南面的墙)。
内壁被定义了两次;
模块1,1中向南的墙也表示为模块2,1中向北的墙。
城堡总是至少有两个房间。
输出
您的程序将写入标准输出:首先是房间的数量,然后是最大房间的面积(以模块计算)。
理解
1.逐个访问房间,没算进去就算一个。宽搜能到达的所有房间。
2.墙数和=1+2+4+8。有8就是有右墙,减掉后,看有没有4,以此类推。
3.往左,就要判断到达房间有没有右墙
往左是0,对于到达房间判断右墙2,
往上是1,对于到达房间判断下墙3
往右是2,对于到达房间判断左墙0
往下是3,对于到达房间判断上墙1
代码
#include <bits/stdc++.h>
using namespace std;
struct room{
bool w[5],//有无左上右下四堵墙
k;//该房间算了没
int x,y,//坐标
n,//该套房子房间数
id;//该房间是哪一套
void set(int d,int xx,int yx){
x=xx,y=yx;
k=0,n=1;
if(d>=8)w[3]=1,d-=8;//下
if(d>=4)w[2]=1,d-=4;//右
if(d>=2)w[1]=1,d-=2;//上
if(d>=1)w[0]=1,d-=1;//下
}
}r[55][55];
int m,n,//行列数
dx,//该房间墙数和
z,//共有几套放
maxd,//所有套间的最大房间数
d[4][2]={{0,-1},{-1,0},{0,1},{1,0}};//左上右下顺序算房间
queue q;//宽搜队列
bool ok(int f,int x,int y){
//确定该坐标有没有房间,算过没,0123左上右下该墙有没有
if(f<2)f+=2;else f-=2;//往左0去,到达房间就是判断右墙2;1,判断3;2判0,3是1
return x>=1&&x<=m&&y>=1&&y<=n&&!r[x][y].k&&!r[x][y].w[f];
}
void view(){
cout<<“房间”<<endl;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)cout<<r[i][j].id<<“,”<<r[i][j].n<<“\t”;
cout<<endl;
}
}
int main(){
//freopen(“data.cpp”,“r”,stdin);
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
cin>>dx;
r[i][j].set(dx,i,j);//确定有哪些墙
}
int x,y,
rn;//房间数
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)//遍历每个房间
if(!r[i][j].k){//没算过该房间
z++;rn=1;//套件总数增加,房间数从0开始
q.push(r[i][j]);r[i][j].k=1;r[i][j].id=z;
while(!q.empty()){
room rx=q.front();q.pop();
for(int di=0;di<4;di++){
x=rx.x+d[di][0],y=rx.y+d[di][1];
if(ok(di,x,y)){
r[x][y].k=1,r[x][y].n=++rn;
r[x][y].id=z;
maxd=max(maxd,rn);
q.push(r[x][y]);
}
}
}
//view();
}
cout<<z<<“\n”<<maxd<<endl;
return 0;
}
小结
队列,宽搜就能完成。
关键就是墙数和=1+2+4+8,得要拆解。
还有往左走,就得判断左边房间得右墙。