USACO 2.1.1 城堡 The Castle

题解

比较有意思的一道题目。大体概念是图搜索和洪水填充。
前两个问题用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;
}

猜你喜欢

转载自blog.csdn.net/smmyy022/article/details/81166792
今日推荐