题解
比较有意思的一道题目。大体概念是图搜索和洪水填充。
前两个问题用dfs就可以解决,后两问遍历对所有房间,检验N和E墙即可。
思路很清楚,但写起来还是要仔细。
代码
/*
PROG:castle
ID:imking022
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
int n,m,ans,mark;
int cot[51][51],mk[51][51];
bool vis[51][51];
int reff[4][2] = { {0,-1}, {-1,0}, {0,1}, {1,0} };
int mk_n[2501];
int cur_size=0,max_size=0;
int ppow(int k){ // 2^k
int r=1;
while(k--) r*=2;
return r;
}
void dfs(int a, int b){
vis[a][b] = true;
mk[a][b] = mark;
cur_size++;
int px,py;
for(int i=0;i<4;i++){
px = a+reff[i][0],py= b+reff[i][1];
if( ( (ppow(i) & cot[a][b]) == 0) &&
px>=0 && px <n &&
py>=0 && py <m
)
if( vis[px][py]==false )
dfs(px,py);
}
}
int main(void){
cin>>m>>n;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>cot[i][j];
memset(vis,false,sizeof(vis));
int blocks = 0;
mark=-1;
// cal for blocks num and max room size
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(!vis[i][j]){
cur_size=0;
mark++;// room mark
dfs(i,j);
blocks++;
mk_n[mark] = cur_size;// mark -> room size
max_size = max(max_size,cur_size);
}
}
// search for the wall
int max_d_size = 0, xx,yy;
bool north;
for(int j=0;j<m;j++) // from S to N, W to E
for(int i=n-1;i>=0;i--){
if(i!=0)// edge
if(( ppow(1) & cot[i][j]) !=0 &&
mk[i][j]!=mk[i-1][j] ){// north wall exist && not in same room
if( mk_n[mk[i][j]] +mk_n[ mk[i-1][j]] > max_d_size){
xx = i, yy = j;
max_d_size =mk_n[ mk[i][j]]+mk_n[mk[i-1][j]];
north = true;
}
}
if(j!=m-1)// edge
if(( ppow(2) & cot[i][j]) !=0 &&
mk[i][j]!=mk[i][j+1]){// east wall exist && not in same room
if( mk_n[mk[i][j]] + mk_n[mk[i][j+1]] > max_d_size){
xx = i, yy = j;
max_d_size = mk_n[mk[i][j]]+mk_n[mk[i][j+1]];
north = false;
}
}
}
cout<<blocks<<endl <<max_size<<endl;
cout<< max_d_size<< endl<<xx+1<<" " <<yy+1;
if(north) cout<<" N"<<endl;
else cout<<" E"<<endl;
return 0;
}