分析:先暴力求出联通块数和最大联通块包含多少,接着对于每个位置判断去掉其上下左右的四个位置的墙之后的最大联通块数,并且记得先选最西,然后选最南的顺序了来输出
1 /* 2 PROB:castle 3 ID:wanghan 4 LANG:C++ 5 */ 6 #include "iostream" 7 #include "cstdio" 8 #include "cstring" 9 using namespace std; 10 const int maxn=50+10; 11 int n,m,a[maxn][maxn],vis[maxn][maxn]; 12 int ans,cnt; 13 int dx[]={ 0,-1,0,1}; 14 int dy[]={-1,0,1,0}; 15 int r[]={ 1,2,4,8}; 16 bool judge(int x,int y){ 17 if(x>n||x<=0||y<=0||y>m) 18 return false; 19 return true; 20 } 21 void dfs(int x,int y){ 22 if(vis[x][y]) 23 return ; 24 vis[x][y]=1; 25 ans++; 26 for(int i=0;i<4;i++){ 27 int sx=x+dx[i],sy=y+dy[i]; 28 if(judge(sx,sy)){ 29 if((a[x][y]&r[i])==0) 30 dfs(sx,sy); 31 } 32 } 33 /* 34 if((a[x][y]&1)==0) dfs(x,y-1); 35 if((a[x][y]&2)==0) dfs(x-1,y); 36 if((a[x][y]&4)==0) dfs(x,y+1); 37 if((a[x][y]&8)==0) dfs(x+1,y);*/ 38 } 39 int main() 40 { 41 freopen("castle.in","r",stdin); 42 freopen("castle.out","w",stdout); 43 cin>>m>>n; 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<=m;j++) 46 cin>>a[i][j]; 47 } 48 memset(vis,0,sizeof(vis)); 49 cnt=0; 50 int res=0; 51 for(int i=1;i<=n;i++){ 52 for(int j=1;j<=m;j++){ 53 if(!vis[i][j]){ 54 ++cnt; 55 ans=0; 56 dfs(i,j); 57 res=max(res,ans); 58 } 59 } 60 } 61 cout<< =1;i--){ 68 if((a[i][j]&1)){ 69 memset(vis,0,sizeof(vis)); 70 ans=0; 71 a[i][j]-=1; 72 dfs(i,j); 73 if(ans>res){ 74 res=ans; 75 x=i,y=j; 76 ch=""; 77 ch="W"; 78 } 79 a[i][j]+=1; 80 } 81 if((a[i][j]&2)){ 82 memset(vis,0,sizeof(vis)); 83 ans=0; 84 a[i][j]-=2; 85 dfs(i,j); 86 if(ans>res){ 87 res=ans; 88 x=i,y=j; 89 ch=""; 90 ch="N"; 91 } 92 a[i][j]+=2; 93 } 94 if((a[i][j]&4)){ 95 memset(vis,0,sizeof(vis)); 96 ans=0; 97 a[i][j]-=4; 98 dfs(i,j); 99 if(ans>res){100 res=ans;101 x=i,y=j;102 ch="";103 ch="E";104 }105 a[i][j]+=4;106 }107 if((a[i][j]&8)){108 memset(vis,0,sizeof(vis));109 ans=0;110 a[i][j]-=8;111 dfs(i,j);112 if(ans>res){113 res=ans;114 x=i,y=j;115 ch="";116 ch="S";117 }118 a[i][j]+=8;119 }120 }121 }122 cout< <