Good Bye 2017 E. New Year and Entity Enumeration

先按照绿点进行分块
第一个绿点和最后一个绿点之后很好处理不说了

两个绿点之间的讨论:
有两种方案
1:红(蓝)点和绿点顺序连接,距离为相邻绿点距离(也就是双倍绿点距离)
2:红(蓝)点和绿点的点阵中寻找最大的距离边,不连这一条,其他都顺序连,当然这样不连通,最后再绿点连接。(一个绿点距离+红(蓝)点阵处理 可以看到样例就是这样做的)

#include<iostream>
#include<map>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 3e5+5;
#define MS(x,y) memset(x,y,sizeof(x))
#define MP(x, y) make_pair(x, y)

int dis[N]; int color[N];


vector<int> so;
int main() {
    int n;
    while(~scanf("%d", &n)) {
        so.clear();
        for(int i = 0; i < n; ++i) {
            int a; char b[10];
            scanf("%d %s", &a, b);
            dis[i] = a; 
            color[i] = b[0]=='G'? 3 : (b[0]=='R'? 1:2);
        }

        int ans = 0; 
        for(int i = 0; i < n; ++i) {
            if(color[i] == 3) {
                so.push_back(i);        
            }
        }

        if(so.empty()) {
            int st = -1, ed = 0;
            for(int i = 0; i < n; ++i) {
                if(color[i] == 1 && st == -1) st = i;
                if(color[i] == 1) ed = i;
            }
            if(st != -1) ans += dis[ed] - dis[st];

            st = -1; ed = 0;
            for(int i = 0; i < n; ++i) {
                if(color[i] == 2 && st == -1) st = i;
                if(color[i] == 2) ed = i;
            }
            if(st != -1) ans += dis[ed] - dis[st];

            printf("%d
", ans);
            continue;
        }

        //1
        for(int i = 0; i < so[0]; ++i) {
            if(color[i] == 1)   {
                ans += dis[so[0]] - dis[i]; break;
            }
        }
        for(int i = 0; i < so[0]; ++i) {
            if(color[i] == 2)   {
                ans += dis[so[0]] - dis[i]; break;
            }
        }

        //2
        for(int i = 0; i <= so.size()-2; ++i) {
            int len = dis[so[i+1]] - dis[so[i]];
            int tt = 0;
            int maxx = 0; int pre = so[i];
            for(int j = so[i] + 1; j <= so[i+1]; ++j) {
                if(color[j] != 1 ) {
                //  printf("%d
", j);
                    maxx = max(maxx, dis[j] - dis[pre]);
                    pre = j;
                }
            }
            tt += dis[so[i + 1]] - dis[so[i]] - maxx;

            maxx = 0; pre = so[i];
            for(int j = so[i] + 1; j <= so[i+1]; ++j) {
                if(color[j] != 2) {
                    maxx = max(maxx, dis[j] - dis[pre]);
                    pre = j;
                }
            }
            tt += dis[so[i + 1]] - dis[so[i]] - maxx;

            if(tt > len) tt = len;
            tt += len;
            ans += tt;  

        }


        //3
        for(int i = n-1; i > so[so.size()-1]; --i) {
            if(color[i] == 1) {
                ans += dis[i] - dis[so[so.size()-1]]; break;
            }
        }
        for(int i = n-1; i > so[so.size()-1]; --i) {
            if(color[i] == 2) {
                ans += dis[i] - dis[so[so.size()-1]]; break;
            }
        }


        printf("%d
", ans);
    }
    return 0;
}