信息学奥赛一本通(1250:The Castle)
1250:The Castle
時間限制: 1000 ms ??? ??? 內存限制: 65536 KB
提交數: 5332 ??? 通過數: 2746
【題目描述】
一座城堡被分成m*n個方塊(m≤50,n≤50),每個方塊可有0~4堵墻(0表示無墻)。下面示出了建筑平面圖:
圖中的加粗黑線代表墻。幾個連通的方塊組成房間,房間與房間之間一定是用黑線(墻)隔開的。
現在要求你編一個程序,解決以下2個問題:
1、該城堡中有多少個房間?
2、最大的房間有多大?
【輸入】
平面圖用一個數字表示一個方塊(第1個房間用二進制1011表示,0表示無東墻,用十進制11表示)。
第一行一個整數m(m≤50),表示房子南北方向的長度。
第二行一個整數n(n≤50),表示房子東西方向的長度。
后面的m行,每行有n個整數,每個整數都表示平面圖對應位置的方塊的特征。每個方塊中墻的特征由數字P來描述(0≤P≤15)。數字P是下面的可能取的數字之和:
1(西墻 west)
2(北墻 north)
4(東墻 east)
8(南墻 south)
室內的墻被定義兩次: 例如方塊(1,1)中的南墻也被位于其南面的方塊(2,1)定義了一次。
建筑中至少有兩個房間。
【輸出】
第1行:一個整數,表示房間總數;
第2行:一個整數,表示最大房間的面積(方塊數)。
【輸入樣例】
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【分析】
? ? ? ? 這道題和圖的連通性問題一樣,向四個方向探索,能走通則房間數目+1。
【參考代碼1】
C代碼如下:
#include<stdio.h>int map[51][51][4]; int d,m,n,i,j; int num=0,maxmj; //num為房間數,maxmj為房間最大面積 int dx[4]={0,1,0,-1}; // 方向數組 int dy[4]={1,0,-1,0}; int fj[51][51]={0}; //fj[x][y],(x,y)坐標所在的房間號 //map[i][j][0]記錄第i行第j列的房間南邊是否有墻,=1,有墻,=0無墻 //map[i][j][1]記錄第i行第j列的房間東邊是否有墻,=1,有墻,=0無墻 //map[i][j][2]記錄第i行第j列的房間北邊是否有墻,=1,有墻,=0無墻 //map[i][j][3]記錄第i行第j列的房間西邊是否有墻,=1,有墻,=0無墻int que[2501][3]; //que為隊列,q[i][0]為隊列中第i個房間的橫坐標,q[i][1]為縱坐標 void bfs(int p,int q) //從第p行第q列的房間開始廣搜 {int t;int p1=p,q1=q;int fjmj=1; //房間的面積 int head=0,tail=1,x1,y1,x,y;num++; //找到的房間數加1fj[p1][q1]=num; //貼上房間號 que[1][0]=p1;que[1][1]=q1;while(head<tail){head++;for(t=0;t<=3;t++)//右、下、左、上四個方向搜索 {x1=que[head][0];y1=que[head][1];x=x1+dx[t];y=y1+dy[t];if(1<=x && x<=m && 1<=y && y<=n && (fj[x][y]==0))//未超出邊界 {//t=0,1,2,3,分別向右、向下,向左、向上搜索if(map[x][y][3-t]==0 && map[x1][y1][(5-t)%4]==map[x][y][3-t]){//入隊tail++; fj[x][y]=num;//貼上房間號 fjmj++;que[tail][0]=x;que[tail][1]=y;}} }}if(maxmj<fjmj)maxmj=fjmj;return; } int main() {scanf("%d%d",&m,&n);//m行n列for(i=1;i<=m;i++)for(j=1;j<=n;j++){scanf("%d",&d);if(d==15) //d=15,這個小房間四面都是墻{num++; //生成新的房間號 if(maxmj<1)maxmj=1;fj[i][j]=num;//貼上新房間號 }int t=3;while(d>0)//將輸入的數字轉為二進制,并保存在數組中 {map[i][j][t]=d%2;d=d/2;t--;}}for(i=1;i<=m;i++){for(j=1;j<=n;j++){ if(fj[i][j]==0)//房間號為0,第i行第j列不屬于一個房間 bfs(i,j);} } printf("%d\n%d\n",num,maxmj);return 0; }【參考代碼2】
C++代碼如下:
#include<iostream> #include<cstring> #include<queue>using namespace std;struct node {int x;int y; };int n,m; //地圖尺寸 int mp[255][255][6]; //地圖數組,mp[i][j][0]記錄是第幾個房間,mp[i][j][1..4]記錄該方向是否有障礙 int dir[5][2]={{0},{0,-1},{-1,0},{0,1},{1,0}}; //方向數組 int a[5]={0,1,2,4,8}; //障礙數組 int ans; //房間數目 void bfs(int x,int y,int t) {queue <node>q;node s,tmp;s.x=x;s.y=y; q.push(s);ans++;mp[x][y][0]=t;while(!q.empty()){node nw=q.front();for(int i=1;i<=4;i++){int x1=nw.x+dir[i][0];int y1=nw.y+dir[i][1];tmp.x=x1;tmp.y=y1;if(x1>0 && x1<=m && y1>0 && y1<=n && !mp[nw.x][nw.y][i] && !mp[x1][y1][0]){mp[x1][y1][0]=t;q.push(tmp);ans++;}}q.pop();} } int main() {cin>>m>>n;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){int p;cin>>p;for(int k=4;k>0;k--){if(p-a[k]>=0){p-=a[k];mp[i][j][k]=1;}}}}int t=1; //房間總數 int maxn=0; //最大房間數 for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){if(!mp[i][j][0]){bfs(i,j,t++);maxn=max(maxn,ans);ans=0;}}}cout<<t-1<<endl<<maxn<<endl; }http://ybt.ssoier.cn:8088/problem_show.php?pid=1250
總結
以上是生活随笔為你收集整理的信息学奥赛一本通(1250:The Castle)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息学奥赛一本通(1192:放苹果)
- 下一篇: 信息学奥赛一本通(1203:扩号匹配问题