原題目鏈接:
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