AtCoder Beginner Contest 351 D题 Grid and Magnet

D题:Grid and Magnet

标签:搜索
题意:给定一个 n n nx m m m的地图,地图中 # 表示不可以走,. 表示可以走。在此基础上加上一个限制,如果一个 . 周围上下左右中有一个位置有 #,就不能移动。求从 . 的地方走最多能到达的格子数。
题解:如果没有限制,就是普通的搜索了,暴力跑就好了。加上这个限制,如果我们像连通块一样,提前把某个格子跑到,并且因为 周围上下左右有一个#就不能移动,提前打上标记。后面其实从其他位置出发也能跑到这个格子,这个格子的计数就少了。
那如果我们跑每个点的时候,都对整张地图的 v i s vis vis 标记 m e m s e t memset memset 重置一下,那么总的时间复杂度又太大了。
这边可以引入一个类似标记第几个连通块的 i d id id,我们跑每个没有被标记的点,在跑的过程中发现如果能走到的下个点的 v i s vis vis标记和当前标记不一样,也让它跑下去,并打上当前 i d id id,这样就能统计到所有能够跑到的点。
代码

#include <bits/stdc++.h>
using namespace std;

int n, m, cnt, ans = 0, num = 0;
char s[1005][1005];
int vis[1005][1005];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

bool check(int x, int y) {
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (s[nx][ny] == '#') return 0;
    }
    return 1;
}

void dfs(int x, int y, int id) {
    cnt++;
    vis[x][y] = id;
    if (!check(x, y)) return ;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
        // 这边不判s[nx][ny]=='#' 因为前面check有判过了
        if (vis[nx][ny] == vis[x][y]) continue;
        dfs(nx, ny, id);
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
    cin >> s[i][j];

    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
        if (s[i][j] == '.' && !vis[i][j]) {
            cnt = 0;
            ++num;
            dfs(i, j, num);
            ans = max(ans, cnt);
        }
    }

    cout << ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值