2019牛客多校九 J Symmetrical Painting(思维模拟)

本文介绍了一种通过枚举平分线,寻找最优矩形区域涂色策略的算法。通过对每个矩形的上下边界和中点进行分析,利用对称性原理,实现了矩形区域面积的最大化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

题意:
给出 n n n个长为1, 以及下边界 L L L和上边界 R R R的矩形,每个矩形初始时涂上黑色。你可以将某些矩形区域涂上白色,涂完后求最大的矩形区域面积,满足存在一条平行于 x x x轴的直线平方上下两部分矩形区域面积(即直线上下的黑色部分面积相同)

思路:
考虑枚举平分线,会发现对于一个矩形来说,平分线越靠近矩形中点,那么我们需要涂色的面积就越小(因为对称,画个图感受一下。),获得的黑色区域面积就越大。到达中点时获得的面积最大就是矩形的面积。再往上移动平分线,那么我们需要涂色的面积就越来越大,获得的黑色面积就越小。

发现这个规律后就可以通过枚举每个矩形的上中下三个边界来确定面积。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector> 
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x)  x&-x;  
#define debugint(name,x) printf("%s: %d\n",name,x);
#define debugstring(name,x) printf("%s: %s\n",name,x);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e6+5;
const int mod = 1e9+7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n;
struct node{
    ll border;
    int sta;
    bool operator<(const node C)const {
        return border < C.border;
    }
}w[maxn];

int main(){
    scanf("%d",&n);
    int tot = 0;
    for(int i = 1; i <= n; i++){
        int l,r;
        scanf("%d%d",&l,&r);
        l <<= 1, r <<= 1;
        w[++tot].border = l, w[tot].sta = 1; //1表示当前到达了矩形上下边界,再往上枚举边界面积将会变大
        w[++tot].border = (l+r)>>1,  w[tot].sta = -2;  //-2表示当前到达了矩形中点,再往上枚举边界面积将会变小
        w[++tot].border = r, w[tot].sta = 1;
    }
    sort(w+1,w+tot+1);
//    for(int i = 1; i <= tot; i++)
//	printf("%lld %d\n",w[i].border,w[i].sta); 
    w[0].border = w[1].border;
    ll add = 0, sum = 0, area = 0, ans = 0;
    for(int i = 1; i <= tot; i++){
        area = w[i].border - w[i-1].border;
        sum += area*add;
        ans = max(ans, sum);
        add += w[i].sta; 
    }
    printf("%lld\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值