zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第九场)J Symmetrical Painting (思维)

    传送门
    大体思路就是:枚举所有可能的水平对称线,计算面积更新答案。

    所有可能的水平对称线:(L_i,R_i,{L_i+R_iover 2})

    计算面积:将所有可能的水平对称线从小到大排序,然后依次计算。

    假设算出了第(i-1)条对称线的答案,然后更新第(i) 条的,两个的高度差为(h)

    对于块1,贡献多了(2h),对块2并没有贡献。

    当更新第(i+1)条时,高度差为(h_2),对块1的贡献为(2h_2),对块2的贡献为(2h_2)

    当更新第(i+2)条时,高度差为(h_3),对块1的贡献为(-2h_3),对块2的贡献为(2*h_3)

    (cdots)

    可以发现,如果枚举的对称线过了某个块的底线,那么这个贡献就是高度差的2倍,如果过了该块的对称线,贡献就是负的高度差的2倍,如果过了顶线,贡献为0。

    所以要时刻记录以下两种块的数量差:

    [已过底线但未过对称线 - 已过对称线但未过顶线 ]

    体现在程序中可以通过底线时,个数++,通过对称线时,个数-2,通过顶线++

    另外可以先把高度都乘2,在计算过程中就不必再乘2了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 300010;
    typedef pair<int,int> pii;
    vector<pii> v;
    int n;
    int main(){
        scanf("%d",&n);Q
        for(int i=1;i<=n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            v.push_back({x+x,1});
            v.push_back({x+y,-2});
            v.push_back({y+y,1});
        }
        sort(v.begin(),v.end());
        ll res = 0,sum = 0,last = 0,sz = 0;
        for(auto x : v){
            sum += sz * (x.first - last);
            res = max(res,sum);
            sz += x.second;
            last = x.first;
        }
        cout<<res<<endl;
        return 0;
    }
    
  • 相关阅读:
    vuerouter-2.路由跳转
    vuerouter-1.路由基础
    vuebase-11._跨域处理
    vuebase-10_Axios配置
    vuebase--9._axios post请求
    vuebase--8._axios
    vuebase-7.过滤器
    vuebase-6.自定义指令
    vuebase-5.过渡和动画
    vuebase---4.实例生命周期
  • 原文地址:https://www.cnblogs.com/1625--H/p/11383636.html
Copyright © 2011-2022 走看看