UVALive 7261 Xiongnu's Land【差分】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41785863/article/details/101945110

题目链接:https://vjudge.net/problem/UVALive-7271

题意:给你一个n*n的矩形区域,左下角是(0,0),然后给你m个区域内的小矩形,然后让你从某个竖线划分开,使得

1.左边小矩形总面积大于等于右边的,并且使差值尽可能小。

2.在满足条件1的情况下使得竖线尽可能往右。

思路:我们假设在x处分开,然后我们考虑如果在x+1处分开会有什么影响,根据差分的思想,或者说是扫描线?每个小矩形对这段区间的贡献,差分一下,然后求个前缀和就是竖线右移会产生的影响,我们就从0枚举到n就可以找到最优解了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll a[maxn];
struct node
{
    int x, y, w, h;
}b[maxn];

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n, m;
        scanf("%d%d", &n, &m);
        memset(a, 0, (n + 1) * sizeof(ll));
        ll sum = 0;
        for(int i = 1; i <= m; ++i)
        {
            scanf("%d%d%d%d", &b[i].x, &b[i].y, &b[i].w, &b[i].h);
            a[b[i].x + 1] += b[i].h, a[b[i].x + b[i].w + 1] -= b[i].h;
            sum += 1ll * b[i].w * b[i].h;
        }
        for(int i = 1; i <= n; ++i)
            a[i] += a[i - 1];
        int ans = 0;
        ll res = 0, Min = inf;

        for(int i = 0; i <= n; ++i)
        {
            res += a[i];
            if(res * 2 >= sum && Min >= res)
            {
                Min = res;
                ans = i;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41785863/article/details/101945110