【2021牛客多校8F】Robots (bitset)

题目链接

题目大意

一个网格地图,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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值