USACO2.1.1 The Castle (castle)

来源:互联网 发布:linux stdin 编辑:程序博客网 时间:2024/06/05 22:50

用一个二维数组记录每个格的四面是否有墙,根据输入,利用位运算得出每个格的墙的情况(8 = 23,4 = 22,2 = 21,1 = 20)。 然后用floodfill,对每个房间染色,求出房间数,和每个房间的面积,输出其中最大的。

枚举每堵墙,如果墙的两边不是同一个房间且其面积和更大,更新结果,为了结果唯一,我们从左下向右上,一列一列枚举格子,并且先枚举该格上面的墙再枚举右边的。有多解时选(重心)最靠西的(仍然有多解时选这些里面(重心)最靠南的), 请注意重心二字! 北墙的重心当然比东墙的要靠西啊



/*ID:xsy97051PROB:castleLANG:C++*/#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int N,M,tc,num,ansx,ansy;char ansc;int map[100][100],tick[100][100],color[10000];int d_x[9] = {0,0,-1,0,0,0,0,0,1}; // 1 2 4 8 int d_y[9] = {0,-1,0,0,1,0,0,0,0}; // W N E Schar p[9] = {' ','W','N',' ','E',' ',' ',' ','S'}; void dfs(int x, int y) // flood-fill{    int st=map[x][y];    tick[x][y]=tc;    ++color[tc];    while (st!=15)    {        int k=(~st) & (st+1);        if (!tick[d_x[k]+x][d_y[k]+y])           dfs(d_x[k]+x,d_y[k]+y);        st=(st|k)&15;    }} void breakwall(int x,int y,int dir){    int xx=x+d_x[dir], yy=y+d_y[dir];    int tot=0;    if(xx>0 && yy>0 && xx<=N && yy<=M)       if(tick[xx][yy]!=tick[x][y])            tot=color[tick[xx][yy]]+color[tick[x][y]];       else             tot=color[tick[x][y]];        if(tot>num)    {        num=tot;        ansx=x;        ansy=y;        ansc=p[dir];     }    return;}int main(){    freopen("castle.in","r",stdin);    freopen("castle.out","w",stdout);    cin>>M>>N;    for(int i=1;i<=N;++i)        for(int j=1;j<=M;++j)       cin>>map[i][j];    for(int i=1;i<=N;++i)                       for(int j=1;j<=M;++j)            if(!tick[i][j])    {        ++tc;        dfs(i,j);                 //   flood-fill       }    for (int i=1;i<=tc;++i)    num=max(num,color[i]);            cout<<tc<<endl<<num<<endl;    for(int j=1;j<=M;++j)        for(int i=N;i>=1;--i)        {            breakwall(i,j,1<<1); // north            breakwall(i,j,1<<2); // east        }            cout<<num<<endl<<ansx<<" "<<ansy<<" "<<ansc<<endl;    return 0;}



0 0
原创粉丝点击