牛客小白月赛95题(补题 二维差分)

补题 F 牛客小白周赛95

讲一下 F题 

最开始做这一题的时候,想到差分了,but是曼哈顿距离的差分,不太会写,,现在课后补题,这种思路其实很经典就是,将曼哈顿距离转换为切比雪夫距离。

通过学习曼哈顿距离转切比雪夫距离 我们可以知道 ,这两个距离可以互相转换。

对于曼哈顿距离中的点(x,y) 我们转换为切比雪夫坐标系下的坐标 如下

(x,y)→ (x+y,x-y) 

而切比雪夫距离转换为曼哈顿距离则是 (x,y)→ (\frac{x+y}{2},\frac{x-y}{2})  

将这个旋转的图形转换为正置的图形 ,则可以使用二维差分模板了

代码如下

#include <iostream>
#include <vector>
#include <tuple>

using namespace std;

int main() {
    int n, q;
    cin >> n >> q;

    vector<tuple<int, int, int>> arr;
    for (int i = 0; i < q; ++i) {
        int y, x, r;
        cin >> y >> x >> r;
        arr.emplace_back(y - 1, x - 1, r);
    }

    int nm = 2 * n + 1;
    vector<vector<int>> diff(nm, vector<int>(nm, 0));

    for (const auto& t : arr) {
        int y = get<0>(t);
        int x = get<1>(t);
        int r = get<2>(t);

        int dy = y + x;
        int dx = y - x + n;
        int a = max(0, dy - r);
        int c = min(2 * n - 1, dy + r);
        int b = max(0, dx - r);
        int d = min(2 * n - 1, dx + r);

        diff[a][b] += 1;
        if (d + 1 < nm) diff[a][d + 1] -= 1;
        if (c + 1 < nm) diff[c + 1][b] -= 1;
        if (c + 1 < nm && d + 1 < nm) diff[c + 1][d + 1] += 1;
    }

    int res = 0;
    for (int i = 0; i < nm; ++i) {
        for (int j = 0; j < nm; ++j) {
            if (i > 0) diff[i][j] += diff[i - 1][j];
            if (j > 0) diff[i][j] += diff[i][j - 1];
            if (i > 0 && j > 0) diff[i][j] -= diff[i - 1][j - 1];

            int sy = (i + j - n) / 2;
            int sx = (i - j + n) / 2;
            if ((i + j - n) % 2 == 0 && 0 <= sy && sy < n && 0 <= sx && sx < n) {
                if (diff[i][j] % 2 == 1) {
                    res += 1;
                }
            }
        }
    }

    cout << res << endl;
    return 0;
}

此外还有abc178的e 178e

leetcode的31023102

分别是求曼哈顿距离的最大值最小值,我们都可以转换为切比雪夫距离来算

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值