• Codeforces-1430D- String Deletion


    D. String Deletion

    题目大意

    给你一个字符串,每次操作可以删除一个字符,然后删除这个字符串从头开始最长相同的字符串,问最多可以操作几次

    解题思路

    (比赛时脑抽,没写出来,又掉了一大波分)

    我们可以采用贪心的方法求解,我们把连续相同地字符看作一个联通块,因此这个字符串就是由许多联通块组成的。那么如果最前面的联通块的长度不是1的话,我们就从这个联通快中删除一个字符,然后连通块的数量-1,如果这个连通块长度为1的话,就从他后面的连通块中选取一个长度不为1的进行删除,然后连通块数量-1,如果后面也没有连通块长度大于1的,则直接输出当前连通块数量/2(向上取整)。

    注意:如果每次都从当前连通块向后找长度不为1的,就会超时,因此我们可以用一个变量来进行标记,指向当前长度不为的1的连通块

    连接

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    const int maxn=2e5+5;
    char s[maxn];
    struct n
    {
        int l,r,flag,len;
    }node[maxn];
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            scanf("%s",s+1);
            int l=1;
            int cnt=0;
            s[n+1]='#';
            for(int i=1;i<=n;i++)
            {
                if(s[i]!=s[i+1])
                {
                    node[++cnt].l=l;
                    node[cnt].r=i;
                    node[cnt].flag=s[i];
                    node[cnt].len=i-l+1;
                    l=i+1;
                }
            }
            long long ans=0;
            int flag=1;
            int bt=cnt;
            int i=1;
    //        for(int i=1;i<=cnt;i++) printf("%d
    ",node[i].len);
            while(cnt>0)
            {
                if(node[flag].len!=1)
                {
        
                    ans++;
                    flag++;
                    cnt--;
                }
                else{
                    bool find=false;
                    i=max(i,flag);
                    i=min(i,bt);
                    for(;i<=bt;i++)
                    {
                        if(node[i].len!=1)
                        {
                            find=true;
                            node[i].len--;
                            flag++;
                            ans++;
                            cnt--;
                            break;
                        }
                    }
                    if(!find)
                    {                
                        ans+=cnt/2;
                        if(cnt%2) ans++;
                        break;
                    }
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    接口和实现接口的类
    类的封装
    实验六:类的封装
    实验五:任意输入10个int类型数据,排序输出,再找出素数
    实验四:采用一维数组输出等腰三角形的杨辉三角
    2017-12-31 小组工作记录
    2017-12-30 小组工作记录
    2017-12-29 小组工作记录
    2017-12-24 小组工作记录
    2017-12-21 小组工作记录
  • 原文地址:https://www.cnblogs.com/tombraider-shadow/p/13804073.html
Copyright © 2020-2023  润新知