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;
}

浙公网安备 33010602011771号