比赛 二进制状态表示之搜索中的应用 评测结果 AAAAAAAA
题目名称 城堡 最终得分 100
用户昵称 ┭┮﹏┭┮ 运行时间 0.050 s
代码语言 C++ 内存使用 0.72 MiB
提交时间 2023-07-26 17:20:00
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
int xx[10],yy[10];//向各个方向的下x,y变化值 
int n,m,ans,s,ss,xx1,yy1,u;
char aa;//ans       ss                     u                   xx1  yy1  aa按顺序输出
//分别为房间数,最大房间面积,去掉其中一块墙的最大房间面积 ,   墙的方位 
int v[110][110];//房间和墙位置数组 
bool w[110][110];//种子填充dfs bool数组 
void init(){
    xx[1] = 0,xx[2] = -1,xx[4] = 0,xx[8] = 1;//1西 2北 4东 8南
    yy[1] = -1,yy[2] = 0,yy[4] = 1,yy[8] = 0;//向各个方向的下x,y变化值 
    scanf("%d%d",&m,&n);
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            int x;
            scanf("%d",&x);//输入 
            v[2*i][2*j] = 1;//房间为1,墙为2,多余的四个角为3 
            while(x){
                int z = x & (-x);
                v[2*i+xx[z]][2*j+yy[z]] = 2;
                x &= (x-1);//墙 
            }
            v[2*i-1][2*j-1] = 3;v[2*i+1][2*j-1] = 3;v[2*i-1][2*j+1] = 3;v[2*i+1][2*j+1] = 3;
            //多余的四个角 
        }
    }
}
void dfs(int x,int y){
    if(v[x][y] == 2 || v[x][y] == 3 || w[x][y])return;
    if(v[x][y] == 1)s++;
    w[x][y] = 1;
    dfs(x+1,y);dfs(x-1,y);dfs(x,y-1);dfs(x,y+1);
}//种子填充dfs查找房间面积 
void chan(){
    memset(w,0,sizeof(w));//清零bool数组 
    for(int j = 2;j <= 2*m;j++){//从左下角枚举到右上角,因为有多解时选最靠西的,仍然有多解时选最靠南的
        for(int i = 2*n;i >= 2;i--){
            if(v[i][j] == 2){
                v[i][j] = 0;s = 0;//去掉墙 
                dfs(i,j);//去掉墙后的房间面积s 
                if(s > u){
                    u = s;//找到最大的s 
                    if(v[i+1][j] == 1)xx1 = i+1,yy1 = j,aa = 'N';
                    else if(v[i][j-1] == 1)xx1 = i,yy1 = j-1,aa = 'E'; 
                    //同一格子北边的墙比东边的墙更优先
//用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位 
                }
                v[i][j] = 2;//回溯 
                memset(w,0,sizeof(w));//回溯 
            }
        }
    }
    return;
}
int main(){
    freopen("castle.in","r",stdin);
    freopen("castle.out","w",stdout);
    init();//输入 
    for(int i = 1;i <= 2 * n;i++){
        for(int j = 1;j <= 2 * m;j++){
            s = 0;//s为房间面积 
            if(v[i][j] == 1 && !w[i][j]){
                ss++;dfs(i,j);
            }
            ans = max(ans,s);//最大房间面积 
        }
    }//种子填充查找有几块房间以及最大的房间面积 
    printf("%d\n%d\n",ss,ans);
    chan();
    printf("%d\n%d %d %c\n",u,xx1/2,yy1/2,aa);
    //  xx1/2 和yy1/2是因为v数组把墙和房间放到了一起,要去掉墙 
    
    return 0;
}