牛客多校第九场 J Symmetrical Painting 计算几何/扫描线

题意:

平面上有几个宽度相同的矩形区域被涂黑了,让你找到一条横线横截若干个矩形,把这些黑色部分抠下来一部分使得它们以这条横线为对称轴,求能抠下来的最大面积。

题解:

在随着对称轴上移的过程中,必然有一部分矩形有效面积在增加,一部分有效面积在减少,一部分有效面积不变。

单个矩形状态发生变化时,仅当对称轴触及下端点,中点,上端点时。

因此预处理出所有矩形的这三个突变点的信息并离散化,然后从下往上遍历,记录每一个时间点这三种状态的矩形共有多少个,以此递推面积。

最优解一定在突变点处出现,记录即可。

为避免浮点运算,将高度乘以二后存入。

#include<iostream>
#include<algorithm>
#define LL long long 
using namespace std;
struct Node{
    int stat;
    LL height;
    friend bool operator <(const Node &a,const Node &b){
        return a.height<b.height;
    }
    Node(){}
    Node(int x,LL y){
        stat=x;height=y;
    }
}node[900005];
int main(){
    int n;
    scanf("%d",&n);
    int cnt=0;
    node[0]=Node(0,0);
    for(int i=1;i<=n;i++){
        LL l,r;
        scanf("%lld %lld",&l,&r);
        node[++cnt]=Node(-1,l*2);
        node[++cnt]=Node(0,l+r);
        node[++cnt]=Node(1,r*2);
    }
    sort(node+1,node+1+cnt);
    int up=0,down=0;
    LL now=0,maxx=0;
    for(int i=1;i<=cnt;i++){
        now+=(node[i].height-node[i-1].height)*(up-down);
        maxx=max(now,maxx);
        if(node[i].stat==-1)up++;
        if(node[i].stat==0)up--,down++;
        if(node[i].stat==1)down--;
    }
    printf("%lld\n",maxx);
    return 0;
}

 

posted @ 2019-08-16 22:23  Isakovsky  阅读(273)  评论(0编辑  收藏  举报