ssl1104-USACO 2.1城堡(foodfill)【图论,广搜】
##前言
由于這道題比較難,有不好描述,我就直接貼題目了。
##Description
以一個幾乎超乎想像的運氣,農民約翰在他的生日收到了一張愛爾蘭博彩的獎券。
這一張獎券成為了唯一中獎的獎券。
農民約翰嬴得愛爾蘭的鄉下地方的一個傳說中的城堡。
吹牛在他們威斯康辛州不算什么,農民約翰想告訴他的牛所有有關城堡的事。
他想知道城堡有多少房間,而且最大的房間有多大。
事實上,他想去掉一面墻來制造一個更大的房間。
你的任務是幫助農民約翰去了解正確房間數目和大小。
城堡的平面圖被分為 M(wide)*N(1 <=M,N<=50)個小正方形。
每個這樣的小正方形有0到4面墻。
城堡在它的外部邊緣總是有墻壁的,好遮擋風雨。
考慮這注解了一個城堡的平面圖:
例子的城堡的大小是7 x 4。
一個 "房間"是平面圖上有連接的"小正方形"的集合。
這個平面圖包含五個房間。(它們的大小是9,7,3,1, 和 8 排列沒有特別的順序)。
移除被箭作記號的墻壁來合并兩個房間來制造最大的可能房間(移除一面墻所能產生的)。
城堡總是至少有二個房間并且總是有一面墻壁以可能被移除。
###Input
地圖以一個表格來儲存,每個數字描述一個小正方形,N行每行M個數來描述這個平面圖。
輸入順序符合那個在上面例子的編號方式。
每個描述小正方形的數字說明小正方形的四面的墻的分布情況,它是下面4個數的和:
1: 在西面有墻
2: 在北面有墻
4: 在東面有墻
8: 在南面有墻
內部的墻壁是會被定義兩次;小正方形(1,1)南面的墻也被指出是小正方形(2,1)北面的墻。
第 1 行: 二個被空格分開的整數: M 和 N
第 2 到 N+1 行: M x N 個整數,每行M個。
###Output
輸出包含一些行:
第 1 行: 城堡的房間數目。
第 2 行: 最大的房間的大小
第 3 行: 移除一面墻能得到的最大的房間的大小
第 4 行: 移除哪面墻
選擇最佳的墻來移除,(選擇最靠西的,如果仍然不能確定,再選擇最靠南的。編者注:墻的位置應該由它的中點來定義)
(【原文】Choose the optimal wall to remove from the set of optimal walls by choosing the wall farther to the west (and then, if still tied, farthest to the south).)
墻壁由它在相鄰的小正方形的西部或南方來命名
最后一行一定要有回車
###Sample Input
7 4
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
###Sample Output
5
9
16
4 1 E
##解題思路
用廣搜求出前2個值。求出每個小方格的對應的房間的大小,然后枚舉一下破壞哪堵墻求最大值。
##代碼
#include<cstdio> #include<iostream> using namespace std; const int W=0,N=1,E=2,S=3;//常量 int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0}; //搜索方向 bool a[51][51][4];//記錄有沒有墻 int head,tail,walk[51][51],ft[2501],mn,maxs,x,n,m; int state[2501][2],c; void bfs(int x,int y) {c++;//標記房間號head=0;tail=1;state[1][0]=x;state[1][1]=y;walk[x][y]=c;//初始化do{head+=1;for (int i=0;i<4;i++) {x=state[head][0]+dx[i];y=state[head][1]+dy[i];int zx,zy;zx=state[head][0];zy=state[head][1];if (walk[x][y]==0 && !a[zx][zy][i] && x<=n && y<=m && x>=1 && y>=1){tail++;state[tail][0]=x;state[tail][1]=y;walk[x][y]=c;//歸入當前房間}}}while (head<tail); } int main() {scanf("%d%d",&m,&n); for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){scanf("%d",&x);if (x>=8) {a[i][j][S]=true;a[i+1][j][N]=true;x-=8;}//南墻if (x>=4) {a[i][j][E]=true;a[i][j+1][W]=true;x-=4;}//東墻if (x>=2) {a[i][j][N]=true;a[i-1][j][S]=true;x-=2;}//北墻if (x>=1) {a[i][j][W]=true;a[i][j-1][E]=true;x-=1;}//西墻} for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)if (!walk[i][j]){mn++;//房間總數bfs(i,j);//搜索maxs=max(maxs,tail);//求最大房間ft[c]=tail;//記錄房間大小}printf("%d\n%d\n",mn,maxs);//輸出maxs=0;x=0;int y=0;char wall='0';//根據題目要求我們可以得知只有可能破壞N或E墻for (int j=1;j<=m;j++)for (int i=n;i>=1;i--) {if (i-1>=1 && a[i][j][N] && walk[i][j]!=walk[i-1][j] && ft[walk[i][j]]+ft[walk[i-1][j]]>maxs)//判斷如果該方向有墻而且不屬于同一個房間{maxs=ft[walk[i][j]]+ft[walk[i-1][j]];x=i;y=j;wall='N';}//同上if (j+1<=m && a[i][j][E] && walk[i][j]!=walk[i][j+1] && ft[walk[i][j]]+ft[walk[i][j+1]]>maxs){maxs=ft[walk[i][j]]+ft[walk[i][j+1]];x=i;y=j;wall='E';}}printf("%d\n%d %d %c",maxs,x,y,wall); }總結
以上是生活随笔為你收集整理的ssl1104-USACO 2.1城堡(foodfill)【图论,广搜】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 巨人网络:前三季度归母净利润 10.85
- 下一篇: ssl1776-游乐场【图论,深搜】