wall[i][j][4]用來存(i,j)這個位置周圍四面牆的狀況,ans用來記房間的數量。若是(i,j)包含在第k個大房間,則f[i][j]=k,這樣之後能夠很方便的比較f[][]的值判斷是否在一個大房間。c[]用來表示第ans個大房間的小房間數,而後dfs分別求包含小房間(i,j)的大房間包含的的小房間數,記錄最大值。最後遍歷每個小房子,經過拆除其周圍的某一面牆得到大房間,記下取得最大房間大小的最大值和取得此值時的(i,j)的位置和牆的方位。 ios
/* ID:jzzlee1 PROG:castle LANG:C++ Dear double_tings: i love you. */ #include<iostream> #include<fstream> #include<cmath> #include<string> #include<cstring> #include<map> using namespace std; int graph[105][105]={0}; bool wall[105][105][4]={0}; //0表明無牆,1有牆 //第三維:0西面,1北面,2東面 3南面 int f[105][105]={0}; //記錄各個連通份量 (第ans個) int c[6000]={0}; //第ans個連通份量房間的數目 ifstream fin("castle.in"); ofstream fout("castle.out"); int n,m,ans; //ans表示房間數 void dfs(int i,int j,int &count)//深度優先遍歷求最大包含小房間(i,j)的大房間包含的的小房間數 { //對於每一個包含(i,j)的大房間,只需dfs一次就可求出count if(i<1||i>m||j<1||j>n||graph[i][j]) return; f[i][j]=ans; graph[i][j]=++count; if(!wall[i][j][0])dfs(i,j-1,count); if(!wall[i][j][1])dfs(i-1,j,count); if(!wall[i][j][2])dfs(i,j+1,count); if(!wall[i][j][3])dfs(i+1,j,count); } int main() { fin>>n>>m; //cin>>n>>m; int temp; for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) { fin>>temp; //cin>>temp; if(temp&1)wall[i][j][0]=1; if(temp&2)wall[i][j][1]=1; if(temp&4)wall[i][j][2]=1; if(temp&8)wall[i][j][3]=1; } ans=0; int max=0; for(int i=1; i <= m; i++ ) for(int j=1; j <= n ; j++) { if(!graph[i][j]) { int count=0; ans++; dfs(i,j,count); if(count>max) max=count; c[ans]=count; } } fout<<ans<<endl; fout<<max<<endl; //cout<<ans<<endl; //cout<<max<<endl; int ii,jj,mmax=0;char ch; for(int j=1; j<=n; j++) for(int i=m; i>=1; i--) //由下而上從左到右遍歷每一個小房間 { //求拆一面牆獲得的最大房間大小 if(wall[i][j][1]&&f[i][j]!=f[i-1][j]&&c[f[i][j]]+c[f[i-1][j]]>mmax) { mmax=c[f[i][j]]+c[f[i-1][j]]; ii=i; jj=j; ch='N'; } if(wall[i][j][2]&&f[i][j]!=f[i][j+1]&&c[f[i][j]]+c[f[i][j+1]]>mmax) { mmax=c[f[i][j]]+c[f[i][j+1]]; ii=i; jj=j; ch='E'; } } fout<<mmax<<endl; fout<<ii<<" "<<jj<<" "<<ch<<endl; //cout<<mmax<<endl; //cout<<ii<<' '<<jj<<' '<<ch<<endl; return 0; }