牛客多校第九场 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; }