• Codeforces 908F New Year and Rainbow Roads


    New Year and Rainbow Roads

    思路:我们考虑两个绿点之间的红点和蓝点, 首先把这些红点和蓝点接到绿点上面绝对不会超过绿点距离的两倍。

    然后我们先把两个绿点连上, 再把绿点经过蓝点到绿点的线连上, 绿点经过红点到绿点的线连上, 这时距离为3倍的绿点间距离,

    然后我们可以在第二条路径和第三条路径上断开一段最长的, 和两个的绿点距离取个最小值,就是这段的贡献。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    using namespace std;
    
    const int N = 3e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, p, dis[N];
    char s[3];
    vector<int> G, R, B;
    
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d%s", &p, s);
            if(s[0] == 'G') G.push_back(p);
            else if(s[0] == 'R') R.push_back(p);
            else B.push_back(p);
        }
        LL ans = 0;
        if(SZ(G)) {
            int S = G[0], T = G[SZ(G)-1];
            if(SZ(R) && R[0] < S) ans += abs(R[0] - S);
            if(SZ(R) && R[SZ(R)-1] > T) ans += abs(R[SZ(R)-1] - T);
            if(SZ(B) && B[0] < S) ans += abs(B[0] - S);
            if(SZ(B) && B[SZ(B)-1] > T) ans += abs(B[SZ(B)-1] - T);
            for(int i = 0; i + 1 < SZ(G); i++) {
                LL l = G[i], r = G[i + 1];
                LL ret = 0, tmp1 = INF, tmp2 = INF;
                int x = lower_bound(R.begin(), R.end(), l) - R.begin();
                int y = lower_bound(R.begin(), R.end(), r) - R.begin() - 1;
                if(x <= y) {
                    tmp1 = min(tmp1, r-l-(R[x]-l));
                    tmp1 = min(tmp1, r-l-(r-R[y]));
                    for(int j = x; j < y; j++) tmp1 = min(tmp1, r-l-(R[j+1]-R[j]));
                } else tmp1 = 0;
                x = lower_bound(B.begin(), B.end(), l) - B.begin();
                y = lower_bound(B.begin(), B.end(), r) - B.begin() - 1;
                if(x <= y) {
                    tmp2 = min(tmp2, r-l-(B[x]-l));
                    tmp2 = min(tmp2, r-l-(r-B[y]));
                    for(int j = x; j < y; j++) tmp2 = min(tmp2, r-l-(B[j+1]-B[j]));
                } else tmp2 = 0;
                ans += min(2 * (r - l), tmp1 + tmp2 + r - l);
            }
        } else {
            if(SZ(R)) ans += R[SZ(R)-1] - R[0];
            if(SZ(B)) ans += B[SZ(B)-1] - B[0];
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    GitHub 的企业版
    我的Tag列表
    .net开发者对android开发一周的学习体会
    Ajax简单聊天B/S
    C#设计模式——享元模式(Flyweight Pattern)
    mongodb的sharding架构搭建
    Java设计模式
    LMAX架构
    Winform开发的常用类库
    C#设置本地网络(DNS、网关、子网掩码、IP)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10408048.html
Copyright © 2020-2023  润新知