Codeforces Round #455 (Div. 2) D. Colorful Points 乱搞,模拟

Codeforces Round #455 (Div. 2)

D. Colorful Points

题意:给出一个字符串,操作:删除掉与相邻字符不同的字符。问可以进行多少次操作。

tags:乱搞。。好费时间-_-怎么最近的CF都是这么恶心的题???

直接暴力写肯定会T,但可以加个优化: 把连续的相同字符看成一个字符。

然后就是乱搞了,模拟删除与合并。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 2000005;

struct Node {
    int si, sum, pre, next;
}p[N];
int cnt, n, sum;
char s[N];
void DEL(int x)
{
    p[p[x].next].pre = p[x].pre;
    p[p[x].pre].next = p[x].next;
}
int main()
{
    scanf("%s", s+1);
    n = strlen(s+1);
    rep(i,1,n-1)
    {
        ++sum;
        if(s[i]!=s[i+1]) {
            p[++cnt] = (Node){ s[i]-'a', sum, cnt-1, cnt+1 };
            sum = 0;
        }
    }
    ++sum;
    p[++cnt]=(Node){ s[n]-'a', sum, cnt-1, cnt+1 };
    int sz=cnt, fir=1, ed=cnt, mi, ans=0;
    while(sz>1)
    {
        mi = min(p[fir].sum, p[ed].sum);
        for(int i=p[fir].next; i<ed; i=p[i].next)
            mi = min(mi, (p[i].sum+1)/2);
        ans += mi;
        for(int i=p[fir].next; i<ed; i=p[i].next)
            if((p[i].sum+1)/2==mi) {
                --sz;
                DEL(i);
            } else {
                p[i].sum -= mi*2;
            }
        if(p[fir].sum==mi) {
            --sz;
            DEL(fir);
            fir = p[fir].next;
        } else {
            p[fir].sum -= mi;
        }
        if(p[ed].sum==mi) {
            --sz;
            DEL(ed);
            ed = p[ed].pre;
        } else {
            p[ed].sum -= mi;
        }

        for(int i=fir; i<ed; i=p[i].next)
        {
            int to = p[i].next;
            while(p[i].si==p[to].si) {
                --sz;
                DEL(to);
                p[i].sum += p[to].sum;
                if(to==ed) {
                    ed = i;
                    break;
                }
                to = p[i].next;
            }
        }
    }
    printf("%d\n", ans);

    return 0;
}
posted @ 2017-12-28 17:12  v9fly  阅读(163)  评论(0编辑  收藏  举报