城堡问题

简介: 原题目链接: NOI题库  166:The Castle   链接:http://noi.openjudge.cn/ch0205/166/    来源:IOI1994NOI题库  1817:城堡问题    链接:http://noi.openjudge.cn/ch0205/1817/问题描述一座城堡被分为m*n个方块,其中m≤50,n≤50,每个方块可有0~4堵墙围在周围(0表示没有墙壁)。

原题目链接:

NOI题库  166:The Castle   链接:http://noi.openjudge.cn/ch0205/166/    来源:IOI1994

NOI题库  1817:城堡问题    链接:http://noi.openjudge.cn/ch0205/1817/

问题描述

一座城堡被分为m*n个方块,其中m≤50,n≤50,每个方块可有0~4堵墙围在周围(0表示没有墙壁)。下面是一个城堡的示意图:

图中的加粗黑线表示墙壁。几个连通的方块组成房间,房间与房间之间一定是用墙壁(粗黑线)隔开的。

现在要编程求解两个问题:1、该城堡有多少个房间?   2、最大房间有多少个方块?

输入格式:

程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤15)描述:用一个数字表示方块周围的墙,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

算法分析:

这个题目用深搜或广搜都可以解决。其实类似于统计水洼数目的这一道题:http://www.cnblogs.com/huashanqingzhu/p/7258841.html

下面分别用广搜和深搜来解决:

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<queue>
  4 #include<stack>
  5 using namespace std;
  6 
  7 struct obj
  8 {
  9     int xx,yy;
 10 };
 11 
 12 int m,n;
 13 int a[52][52]={0};//a[i][j]用来保存(i,j)位置的方块周围的墙壁信息。
 14 int b[52][52]={0};//b[i][j]用来标识(i,j)位置的方块是否在搜索过程中被访问过 
 15 int Count,Max;
 16 
 17 int dx[4]={0,-1,0,1};//左上右下
 18 int dy[4]={-1,0,1,0};
 19 int bitCheck[4]={1,2,4,8};//西、北、东、南各边的墙壁对应的数字 
 20 void BFS(int x,int y);//从(x,y)开始广搜
 21 void DFS(int x,int y);//从(x,y)开始深搜 
 22 void DFS2(int x,int y);//从(x,y)开始深搜,递归实现 
 23 int CNum=0;//用于DFS2(),记录正在搜索的某个房间的方块数目
 24 
 25 int main(int argc, char *argv[])
 26 {
 27     freopen("1817.in","r",stdin);
 28     int i,j;
 29     int t;
 30     
 31     scanf("%d%d",&m,&n);
 32     for(i=0;i<m;i++)
 33     {
 34         for(j=0;j<n;j++)
 35         {
 36             scanf("%d",&a[i][j]);
 37             //printf("%2d ",a[i][j]);
 38         }
 39         //printf("\n");
 40     }
 41     
 42     Count=0;
 43     Max=-1;
 44     for(i=0;i<m;i++)
 45     {
 46         for(j=0;j<n;j++)
 47         {
 48             if(b[i][j]==0)//(i,j)这个位置的方块未曾被搜索访问
 49             {
 50                 //BFS(i,j);
 51                 DFS(i,j);
 52                 //{ CNum=0; DFS2(i,j); Count++; if(CNum>Max) Max=CNum; }
 53             } 
 54         }
 55     }
 56     printf("%d\n%d\n",Count,Max);
 57     return 0;
 58 }
 59 
 60 void BFS(int x,int y)//从(x,y)开始广搜
 61 {
 62     queue<struct obj> q;
 63     struct obj start,temp;
 64     int i,txx,tyy;
 65     int num=0;//正在搜索的这个房间的方块数目 
 66 
 67     start.xx=x;
 68     start.yy=y;
 69     q.push(start);
 70     b[x][y]=1;
 71     num=1;
 72     while(!q.empty())
 73     {
 74         for(i=0;i<4;i++)
 75         {
 76             txx=q.front().xx+dx[i];
 77             tyy=q.front().yy+dy[i];
 78             //不越界,没有墙壁,未曾访问过,三个条件都满足才可以访问
 79             if(txx>=0&&txx<m&&tyy>=0&&tyy<n&&((a[q.front().xx][q.front().yy]&bitCheck[i])==0)&&b[txx][tyy]==0) 
 80             {
 81                 temp.xx=txx;
 82                 temp.yy=tyy;
 83                 b[txx][tyy]=1;
 84                 q.push(temp);
 85                 num++;
 86             }
 87         }
 88         q.pop();
 89     }
 90     Count++;
 91     if(num>Max) Max=num;
 92 }
 93 
 94 void DFS(int x,int y)//从(x,y)开始深搜 
 95 {
 96     stack<struct obj> s;
 97     struct obj start,temp,temp2;
 98     int i,txx,tyy;
 99     int num;//正在搜索的这个房间的方块数目
100     
101     b[x][y]=1;
102     start.xx=x;
103     start.yy=y;
104     s.push(start);
105     num=1;
106     while(!s.empty())
107     {
108         temp=s.top();  s.pop();
109         for(i=0;i<4;i++)
110         {
111             txx=temp.xx+dx[i];
112             tyy=temp.yy+dy[i];
113             //不越界,没有墙壁,未曾访问过,三个条件都满足才可以访问
114             if(txx>=0&&txx<m&&tyy>=0&&tyy<n&&((a[temp.xx][temp.yy]&bitCheck[i])==0)&&b[txx][tyy]==0)
115             {
116                 temp2.xx=txx;
117                 temp2.yy=tyy;
118                 b[txx][tyy]=1;
119                 s.push(temp2);
120                 num++;
121             }
122         }
123     }
124     Count++;
125     if(num>Max) Max=num;
126 }
127 
128 void DFS2(int x,int y)//从(x,y)开始深搜,递归实现.返回正在搜索的这个房间的方块数目 
129 {
130     int i,txx,tyy;
131     
132     b[x][y]=1;
133     CNum++;
134     for(i=0;i<4;i++)
135     {
136         txx=x+dx[i];
137         tyy=y+dy[i];
138         //不越界,没有墙壁,未曾访问过,三个条件都满足才可以访问
139         if(txx>=0&&txx<m&&tyy>=0&&tyy<n&&((a[x][y]&bitCheck[i])==0)&&b[txx][tyy]==0)
140         {
141             //b[txx][tyy]=1;
142             DFS2(txx,tyy);
143         }
144     }
145 }

问题延伸:洛谷1457 

 

相关文章
|
11月前
|
存储 人工智能 弹性计算
600天,我们在沙漠筑“城堡”
600天,我们在沙漠筑“城堡”
80 0
小猴打架
题目描述 一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友。每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友。经过N-1次打架之后,整个森林的小猴都会成为好朋友。 现在的问题是,总共有多少种不同的打架过程。
115 0
小猴打架
|
弹性计算 关系型数据库 MySQL
在知识的海洋里喝水
福建疫情来袭,宿舍上课之际。闲来无事为协会创建一个官网。以便后续纳新等后续各项事宜发布。试运营之后将接入学校官网。
在知识的海洋里喝水
彩铅,胖小鸟
这次画了一只小鸟,胖胖的小鸟,跟我一样胖呢。 图片发自简书App 图片发自简书App
964 0
彩铅练习,夜色中的小鸟
这张好丑,颜色练习 图片发自简书App
842 0
彩铅,梦境
图片发自简书App 图片发自简书App
641 0
月球趣事——月球错觉
月球错觉是对出现在低空的月球感觉比在高空时要大的一种光学错觉,这种光学错觉也会出现在太阳和星座上。月亮错觉最早被提出来的解释是:接近地表的月亮,周围有很多的建筑物可以作为对比,让我们具体觉得月亮很大,相反的,高挂天空的月亮,周围没有什么具体让我们觉得很大的东西当对比(就算有云,云的大小对人们而言是不具体的),因此我们无法具体感受到月亮的大小。
2969 0