百练2815 城堡问题
題目要求
總時(shí)間限制:1000ms
內(nèi)存限制:65536kB
題目描述
Wall
| = No wall
– = No wall
圖1是一個(gè)城堡的地形圖。
請(qǐng)你編寫一個(gè)程序,計(jì)算城堡一共有多少房間,最大的房間有多大。城堡被分割成m*n(m≤50,n≤50)個(gè)方塊,每個(gè)方塊可以有0~4面墻。
輸入
程序從標(biāo)準(zhǔn)輸入設(shè)備讀入數(shù)據(jù)。
第一行是兩個(gè)整數(shù),分別是南北向、東西向的方塊數(shù)。
在接下來(lái)的輸入行里,每個(gè)方塊用一個(gè)數(shù)字(0≤p≤50)描述。
用一個(gè)數(shù)字表示方塊周圍的墻,1表示西墻,2表示北墻,4表示東墻,8表示南墻。
每個(gè)方塊用代表其周圍墻的數(shù)字之和表示。
城堡的內(nèi)墻被計(jì)算兩次,方塊(1,1)的南墻同時(shí)也是方塊(2,1)的北墻。
輸入的數(shù)據(jù)保證城堡至少有兩個(gè)房間。
輸出
城堡的房間數(shù)、城堡中最大房間所包括的方塊數(shù)。
結(jié)果顯示在標(biāo)準(zhǔn)輸出設(shè)備上。
樣例輸入
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://bailian.openjudge.cn/practice/2815/
分析
第一步:先看圖,這就要看想象力了,要把#都想象成墻,然后大致能想象出來(lái)出來(lái)這是一個(gè)城堡的平面圖。
第二步:看輸入,有四個(gè)很奇怪的數(shù)字,1,2,4,8。為什么要用這四個(gè)數(shù)表示東西南北墻?如果把它們轉(zhuǎn)換成二進(jìn)制的數(shù),對(duì)應(yīng)的就是0001,0010,0100,1000,這樣就知道題目的意圖了,用位運(yùn)算進(jìn)行判斷墻面。
第三步:選擇合適的數(shù)據(jù)結(jié)構(gòu)進(jìn)行匹配。把方塊看作是節(jié)點(diǎn),相鄰兩個(gè)方塊之間如果沒有墻,則在方塊之間連一條邊,這樣城堡就能轉(zhuǎn)換成一個(gè)圖。
第四步:問題抽象。
求房間個(gè)數(shù),實(shí)際上就是在求圖中有多少個(gè)極大連通子圖(一個(gè)連通子圖,往里面加任何一個(gè)圖里的其它點(diǎn),就會(huì)變得不連通,那么這個(gè)連通子圖就是極大連通子圖)。
每一個(gè)房間,深度優(yōu)先搜索,從而給這個(gè)房間能夠到達(dá)的所有位置染色。最后統(tǒng)計(jì)一共有用了幾種顏色,以及每種顏色的數(shù)量。
代碼塊
1.需要的變量以及頭文件:
#include <iostream> #include <stack> #include <cstring> using namespace std; int R,C; //行列數(shù) int rooms[60][60]; //存放整個(gè)城堡的方塊 int color[60][60]; //方塊是否染色過的標(biāo)記 int maxRoomArea=0; //用來(lái)表示最大的房間面積 int roomNum=0; //表示當(dāng)前已經(jīng)找到的房間數(shù)目 int roomArea; //表示正在探索的房間的面積2.判斷墻面是否存在:
if((rooms[i][k]&1)==0) //西if((rooms[i][k]&2)==0) //北if((rooms[i][k]&4)==0) //東if((rooms[i][k]&8)==0) //南3.剩下的就是讀入數(shù)據(jù)以及進(jìn)行操作了。
完整代碼
#include <iostream> #include <stack> #include <cstring> using namespace std; int R,C; //行列數(shù) int rooms[60][60]; //存放整個(gè)城堡的方塊 int color[60][60]; //方塊是否染色過的標(biāo)記 int maxRoomArea=0; //用來(lái)表示最大的房間面積 int roomNum=0; //表示當(dāng)前已經(jīng)找到的房間數(shù)目 int roomArea; //表示正在探索的房間的面積 void Dfs(int i,int k) {if(color[i][k]){return ;}++roomArea;color[i][k]=roomNum;if((rooms[i][k]&1)==0) Dfs(i,k-1); //向西走if((rooms[i][k]&2)==0) Dfs(i-1,k); //向北走if((rooms[i][k]&4)==0) Dfs(i,k+1); //向東走if((rooms[i][k]&8)==0) Dfs(i+1,k); //向南走 } int main () {cin>>R>>C;for(int i=1;i<=R;++i){for(int k=1;k<=C;++k){cin>>rooms[i][k];}}memset(color,0,sizeof(color));for(int i=1;i<=R;++i){for(int k=1;k<=C;++k){if(!color[i][k]){++roomNum;roomArea=0;Dfs(i,k);maxRoomArea=max(roomArea,maxRoomArea);}}}cout<<roomNum<<endl;cout<<maxRoomArea<<endl; }感悟
如果看到一個(gè)很復(fù)雜的圖以及題目要求,先把圖匹配合適的數(shù)據(jù)結(jié)構(gòu),然后將問題抽象。
總結(jié)
以上是生活随笔為你收集整理的百练2815 城堡问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《算法竞赛入门经典》 习题4-1(象棋
- 下一篇: 百练4103:踩方格