题目大意
一个网格地图,3种机器人分别可以向下、向右、向右或向下。多组询问,每次给定机器人和起止点,问可达性。
思路
前两种直接看前缀和,最后一种用 bitset O ( n 4 / w ) O(n^4/w) O(n4/w) 乱搞。
代码
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; ++i)
using namespace std;
const int N = 505;
int T;
int n, m;
char s[N][N];
int s1[N][N], s2[N][N];
vector<int> Q[N]; // row
bitset<N * N> b[N]; // col
class que {
public:
int type;
int x1, y1, x2, y2;
bool ans;
que() {}
void read() { scanf("%d%d%d%d%d", &type, &x1, &y1, &x2, &y2); }
void solve() {
if (type == 1) {
if (x1 <= x2 && y1 == y2 && s1[x1 - 1][y1] == s1[x2][y2])
ans = true;
else
ans = false;
} else if (type == 2) {
if (x1 == x2 && y1 <= y2 && s2[x1][y1 - 1] == s2[x2][y2])
ans = true;
else
ans = false;
} else {
int id = (x1 - 1) * m + y1 - 1;
ans = b[y2][id];
}
}
} q[500005];
int main() {
scanf("%d%d", &n, &m);
rep(i, 1, n) { scanf("%s", s[i] + 1); }
rep(i, 1, n) {
rep(j, 1, m) {
s1[i][j] = s1[i - 1][j] + (s[i][j] == '1');
s2[i][j] = s2[i][j - 1] + (s[i][j] == '1');
}
}
int tot;
scanf("%d", &tot);
rep(tt, 1, tot) {
q[tt].read();
if (q[tt].type == 3) {
Q[q[tt].x2].push_back(tt);
} else {
q[tt].solve();
}
}
rep(i, 1, n) {
rep(j, 1, m) {
int id = (i - 1) * m + j - 1;
if (s[i][j] == '1') {
b[j].reset();
} else {
b[j][id] = 1;
if (j > 1) b[j] |= b[j - 1];
}
// printf("%d %d: \n", i, j);
// cout << b[j] << endl;
// printf("\n");
}
for (auto tt : Q[i]) {
q[tt].solve();
}
}
rep(tt, 1, tot) { printf(q[tt].ans ? "yes\n" : "no\n"); }
return 0;
}