城堡问题
来源:互联网 发布:身份证图像识别 java 编辑:程序博客网 时间:2024/06/02 17:23
1817:城堡问题
P.S.如果有需要英文版的同学轻点英文版,需要源代码的同学轻点源代码。
总时间限制: 1000ms 内存限制: 65536kB
描述
1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | # # # # # #---#####---#####---#####---# 3 # | | # # # # # #---#########---#####---#---# 4 # # | | | | # # ############################# (图 1) # = Wall | = No wall - = No wall
图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成mn(m≤50,n≤50)个方块,每个方块可以有0~4面墙。
输入
程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。
输出
城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。
样例输入
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
来源
1164
【代码】
状态: Accepted
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int m,n,ans,cnt,bigest; bool flag[100][100],q[100][100][4]; int map[105][105]; int wayr[4]={0,1,0,-1},wayc[4]={1,0,-1,0}; bool check(int a,int b,int x) { if(a<m&&b<n&&a>=0&&b>=0&&q[a][b][x]&&!flag[a][b]) return 1; return 0; } void dfs(int y,int c) //似于递归 { for(int i=0;i<4;i++)//四种走法 if(check(y+wayr[i],c+wayc[i],i)) { flag[y+wayr[i]][c+wayc[i]]=1; cnt++; //如果走得通,房间数+1,且标记 dfs(y+wayr[i],c+wayc[i]); } //不断递归,到最后cnt就为最大房间数} int main() { scanf("%d%d",&m,&n); for(int l=0;l<m;l++) for(int j=0;j<n;j++) { scanf("%d",&map[l][j]); if(!(map[l][j]&1)) q[l][j][0]=1; //判断走不走得通 if(!(map[l][j]&2)) q[l][j][1]=1; //也是有没有墙 if(!(map[l][j]&4)) q[l][j][2]=1; //i行j列的方块,0表示西墙,1表示北墙,2表示东墙,3表示南墙。 if(!(map[l][j]&8)) q[l][j][3]=1; } for(int l=0;l<m;l++) for(int j=0;j<n;j++) if(!flag[l][j]) //判断走没走过 { flag[l][j]=1; //标记 cnt=1;//房间的包括的方块数(初始都为1),每个房间至少有一个 dfs(l,j); if(cnt>bigest) bigest=cnt; //找到最大房间包括的方块数 ans++; // 房间数 } printf("%d\n%d\n",ans,bigest);}
拓展:
同学们知道为什么要写这些东西吗:
if(!(map[l][j]&1)) q[l][j][0]=1; if(!(map[l][j]&2)) q[l][j][1]=1; if(!(map[l][j]&4)) q[l][j][2]=1; if(!(map[l][j]&8)) q[l][j][3]=1;
首先,取反(!)说明的是:1代表不行,0表示可以,在这里,同学们需要注意。那有些同学又有疑问了:为什么在check函数里判断的时候不加(!)?
bool check(int a,int b,int x) { if(a<m&&b<n&&a>=0&&b>=0&&q[a][b][x]&&!flag[a][b]) return 1; return 0; }
同学们可以仔细看一下check的运用:
if(check(y+wayr[i],c+wayc[i],i))
在这里我们可以知道,check是用来判断能不能走的,也就是用于计算在房间里有多少个方块的。能走得通,自然不能有墙。
回归正题:为什么要写那些东西?
此关系到二进制。首先同学们要知道1、2、4、8用二进制怎么表示?二进制变化如下:
1->0001 2->0010 4->0100 8->1000【精英必知】1、2的0次方为1 ---> 即00012、2的1次方为2 ---> 即00103、2的2次方为4 ---> 即01004、2的3次方为8 ---> 即1000......综上,第n个为:2的(n-1)次方。
通过上面,同学们可以观察到1、2、4、8转换为2进制后,可以很好的辨析出是否相等。
e.g:给你一个28,你能判断它有哪些墙了吗?首先28转换为2进制后为:11100可以对比一下: 0001(1) 0010(2) 0100(4) 1000(8)p.s:用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。同学们可以很清楚的看出28有:东墙、南墙。
所以同学们现在应该清楚了。
if(!(map[l][j]&1)) q[l][j][0]=1; if(!(map[l][j]&2)) q[l][j][1]=1; if(!(map[l][j]&4)) q[l][j][2]=1; if(!(map[l][j]&8)) q[l][j][3]=1;
【意思】找是不是没有西墙、北墙、东墙、南墙。
p.s.同学们喜欢的话可以加关注,顶一个。Tanks!
- 城堡问题
- 城堡问题
- 城堡问题
- 城堡问题
- 城堡问题
- 城堡问题
- 城堡问题
- OPENJUDGE 2815 城堡问题
- OpenJudge - 2815:城堡问题
- openjudge城堡问题
- 百练城堡问题
- 城堡问题(DFS)
- OpenJudge - 2815:城堡问题
- NoiOpenJudge 2.5 城堡问题
- openjudge2815 城堡问题
- 搜索之城堡问题
- 2815:城堡问题
- 城堡问题(The Castle)
- Zookeeper main points
- 虚拟运营商APN、SPN参数、Sim卡名称
- innerHTML属性和动态显示时间案例
- mysql 重置主键自增的值
- 操作系统概述
- 城堡问题
- 【玖哥乱弹】编程语言间的斗争
- 工厂模式
- URLConnection &HttpURLConnection 网络请求
- APN显示虚拟运营商名称(sprd5.0)
- OS X 执行命令加了sudo还是提示Operation not permitted
- CodeForces:Cards
- C++面试中关于智能指针的问题
- 测试人员如何突破自我的瓶颈?