CodeForces 97D Robot in Basement(bitset)题解

题意:

给一个\(n * m\)的图,有一个出口,已知\(n * m\)最外面一圈一定是墙。给一串长度为\(k\)的走路的指令,问所有点按照这个指令走都能走到出口的最短长度是多少。如果走的方向是墙就待在原地。

思路:

显然直接模拟的复杂度为\(O(n * m * k)\),高达\(2e9\),那么我们模拟肯定是要模拟的。那我们想能不能让所有位置同时模拟呢?
我们用\(bitset\)保存每个位置是否有人,那么向上走就是\(bit >> m\),再异或上待在墙前面的人。同理其他都可以做,具体看代码。复杂度大概\(O(\frac{n * m * k}{32})\)

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e5 + 5;
const ll MOD = 998244353;
char s[maxn];
bitset<23000>  can, wall, now;
int main(){
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    can.reset(), wall.reset(), now.reset();
    int tot = 0;
    int out;
    for(int i = 1; i <= n; i++){
        scanf("%s", s + 1);
        for(int j = 1; j <= m; j++){
            if(s[j] == '#') wall[tot] = 1;
            else can[tot] = 1, now[tot] = 1;
            if(s[j] == 'E') out = tot;
            tot++;
        }
    }
    scanf("%s", s);
    if(now.count() == 1) printf("0\n");
    else{
        int ans = -1;
        for(int i = 0; i < k; i++){
            if(s[i] == 'U') now = ((now >> m) & can) | ((wall << m) & now);
            if(s[i] == 'D') now = ((now << m) & can) | ((wall >> m) & now);
            if(s[i] == 'L') now = ((now >> 1) & can) | ((wall << 1) & now);
            if(s[i] == 'R') now = ((now << 1) & can) | ((wall >> 1) & now);
            if(now.count() == 1 && now[out] == 1){
                ans = i + 1;
                break;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

posted @ 2019-08-05 19:56  KirinSB  阅读(157)  评论(0)    收藏  举报