1. 程式人生 > >HihoCoder - 1249 Xiongnu's Land —— 差分陣列

HihoCoder - 1249 Xiongnu's Land —— 差分陣列

題意:

兩個人分一塊橫座標0~R,縱座標無限大的土地,裡面有許多矩形形狀的綠洲,保證綠洲沒有重疊

需要選定一個整數橫座標x,滿足:

1.座標左側的綠洲面積大於等於右側的綠洲面積

2.座標左側的面積要儘可能大

問x是多少

思路:

要滿足第二個條件,只需要從R處向左找第一個滿足條件的位置,問題在如何快速求出左右兩側的綠洲面積

綠洲都是矩形,假設有一個左上角座標XY,寬度W高度H的矩形,我們可以將它看作區間[X,X+W]上值加H

然後利用差分陣列,在X位置加H,在X+W+1位置減H,然後求一下前n項和就是1~i處的綠洲面積,最後遍歷查詢就可以了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 100010
#define mod 1000000007
#define inf 0x3f3f3f3f
int r,n;
ll num[1000100];
int main(int argc, char const *argv[]) {
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(num,0,sizeof num);
        scanf("%d%d",&r,&n);
        for(int i=1;i<=n;i++)
        {
            int x,y,w,h;
            scanf("%d%d%d%d",&x,&y,&w,&h);
            num[x]+=h;
            num[x+w]-=h;
        }
        ll sum=0;
        for(int i=1;i<=r;i++)
        {
            sum+=num[i];
            num[i]=sum+num[i-1];
        }
        int ans=-1;
        ll minn=10000000010;
        for(int i=r;i>=1;i--)
        {
            ll k1=num[i-1];
            ll k2=num[r]-num[i-1];
            if((k1>=k2)&&(k1-k2<minn))
            {
                minn=k1-k2;
                ans=i;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}