USACO :The Castle解题报告

      这是道floodfill题,用DFS对每个square扩展很容易得到room的个数以及面积大小。square扩展时用到位运算,每次扩展到下一个square,应将扩展的入口堵住,避免重复扩展甚至死循环。然后枚举打开每一堵墙(最外围的墙除外),当墙两边不属于同一个房间且面积之和最大时即得解。为了避免排序,应从西向东,从南向北的顺序枚举。
/*
ID: xpli1
PROG: castle
LANG: C++
*/

#include
#include  
#include
#include
using namespace std;

#define OUT cout
#define IN  cin
#define MAXNUM 51*51

ofstream fout ("castle.out");
ifstream fin ("castle.in");

int wall[MAXNUM];
int sq_rm[MAXNUM];
int sq_num[MAXNUM];
int M,N;
int roomnum;
int max_sq_num = -1;
int max_sq_num_move = -1;
int ii,jj;
char direction;

void dfs(int k,int dir){
 if(sq_rm[k]) return;
 sq_rm[k] = roomnum;    
 sq_num[roomnum]++;
 int WALL = wall[k]+dir;  // 将入口堵住
 if(!(WALL & 1)) dfs(k-1,4);
 if(!(WALL & 2)) dfs(k-M,8);
 if(!(WALL & 4)) dfs(k+1,1);
 if(!(WALL & 8)) dfs(k+M,2);
}

void mkbigest(){
 int i,j;
 for(i=0; i  wall[i*M + 0] -= 1;
  wall[i*M + M-1] -= 4;
 }
 for(i=0; i  wall[i] -= 2;
  wall[(N-1)*M+i] -= 8;
 }
 
 int index,rmnum;
 for(j=0; j  for(i=N-1; i>=0; i--){
   index = i*M+j;
   if(wall[index]&2 && sq_rm[index] != sq_rm[index-M]){
    rmnum = sq_num[sq_rm[index]]+sq_num[sq_rm[index-M]];
    if(max_sq_num_move < rmnum){
     max_sq_num_move = rmnum;
     ii = i+1;
     jj = j+1;
     direction = 'N';
    }
   }
  }
  for(i=N-1; i>=0; i--){
   index = i*M+j;
   if(wall[index]&4 && sq_rm[index] != sq_rm[index+1]){
    rmnum = sq_num[sq_rm[index]]+sq_num[sq_rm[index+1]];
    if(max_sq_num_move < rmnum){
     max_sq_num_move = rmnum;
     ii = i+1;
     jj = j+1;
     direction = 'E';
    }
   }
  }
 }
}

int main()
{
 IN >> M >> N;
 int i;
 for(i=0; i  IN >> wall[i];

 for(i=0; i  if(sq_rm[i]) continue; 
  roomnum++;
  dfs(i,0); 
 } 
 OUT<< roomnum << endl;

 for(i=0; i  if(max_sq_num < sq_num[i])
   max_sq_num = sq_num[i];
 }
 OUT << max_sq_num << endl;

 mkbigest();
 OUT << max_sq_num_move << endl;
 OUT << ii << ' ' << jj << ' '<< direction << endl;

 return 0;
}

你可能感兴趣的:(USACO :The Castle解题报告)