• 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
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    CAS 之 集成RESTful API
    RSA客户端js加密服务器C#解密(含源码)
    Java实现文件的RSA和DES加密算法
    对称加密DES和TripleDES
    VCL消息处理机制
    10款你应该了解的开源安全工具
    一个登陆框引起的血案
    npm install -S -D -g 有什么区别
    共享软件中恶意代码插入技术研究
    GyoiThon:基于机器学习的渗透测试工具
  • 原文地址:https://www.cnblogs.com/sbfhy/p/8136702.html
Copyright © 2020-2023  润新知