P1457 [USACO2.1] 城堡 The Castle


分析过程以及代码如下所示

#include <bits/stdc++.h>
using namespace std;
const int N = 100, M = 110, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef long long int LL;
int n, m;
int g[N][N];
#define x first
#define y second
bool st[N][N];
int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};
int room_id[N][N];
int room_area[N]; // 记录每个连通块的面积
int max_area;
typedef pair<int, int> PII;
PII q[N * N];
int bfs(int sx, int sy, int id)
{
    st[sx][sy] = true;
    int hh = 0, tt = 0;
    q[0] = {sx, sy};
    int area = 0;
    while (tt >= hh)
    {
        PII t = q[hh++];        // 取出队头。
        room_id[t.x][t.y] = id; // 把同一个连通块标记成同一个id.
        for (int i = 0; i < 4; i++)
        {
            int tx = t.x + dx[i], ty = t.y + dy[i];
            if (tx < 0 || tx >= n || ty < 0 || ty >= m) // 看是否走出边界。
                continue;
            if (st[tx][ty]) // 看看是否被更新过。
                continue;
            if (g[t.x][t.y] >> i & 1) // 这个地方注意一下。这个是判断有个方向上是不是有墙。
                continue;
            st[tx][ty] = true;
            q[++tt] = {tx, ty};
        }
        area++;
    }
    return area;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> m >> n;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> g[i][j];
        }
    }

    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (!st[i][j])
            {
                room_area[cnt] = bfs(i, j, cnt);
                max_area = max(max_area, room_area[cnt]);
                cnt++;
            }
        }
    }
    cout << cnt << endl;
    cout << max_area << endl;
    int besti = 0, bestj = 0;
    int bestarea = max_area;
    char res;
    for (int j = 0; j < m; j++)
    {
        for (int i = n - 1; i >= 0; i--)
        {
            if (i > 0 && (g[i][j] & 2)) // 枚举北墙,后面这个条件是判断这个地方一定有墙。
            {
                int id1 = room_id[i][j], id2 = room_id[i - 1][j];
                if (id1 != id2)
                {
                    if (room_area[id1] + room_area[id2] > bestarea)
                    {
                        besti = i + 1;
                        bestj = j + 1;
                        res = 'N';
                        bestarea = room_area[id1] + room_area[id2];
                    }
                }
            }
            if (j < m - 1 && (g[i][j] & 4)) // 枚举东墙,后面这个条件是判断这个地方一定有墙。
            {
                int id1 = room_id[i][j], id2 = room_id[i][j + 1];
                if (id1 != id2)
                {
                    if (room_area[id1] + room_area[id2] > bestarea)
                    {
                        besti = i + 1;
                        bestj = j + 1;
                        res = 'E';
                        bestarea = room_area[id1] + room_area[id2];
                    }
                }
            }
        }
    }
    cout << bestarea << endl;
    cout << besti << " " << bestj << " " << res;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值