• CodeForces 578E Walking!


    题意

    略。

    题解

    好毒瘤啊,我最多就口胡第一问的样子吧。

    第一问很显然(跟凤凰县探险队员一样显然),就是每次贪心选长度最大的满足条件的子序列,选不到就折返回来。所以折返的次数很明显就是选出子序列的个数 (-1)

    考虑第二问,很明显不能暴力拼接子序列,这样很容易被 hack。具体方法剩下的题解有讲。

    注意到找到的子序列可以按照开头和结尾分成 (4) 类:LLLRRLRR

    首先有一个性质:可以将所有的 LR 拼在一起得到一个更长的 LRRL 同理。

    接下来 LLRR 有一个特殊的作用,就是将一段 LR 和一段 RL 拼起来,类似于 L...RL...LR...LR...LR...RL...R。(这里两个字母中间三个点表示一段子序列)

    但是有些时候,没有 LLRR,但是有 LRRL,这两段是无法拼起来的。难道我们就这样失败了吗?没有的事!

    我们可以通过已经有的 LRRL 自己造一个 LLRR 出来。具体地话就是考虑 LRRL 中最后一个位置的关系。然后最后一个位置小的那个序列把最后一个位置给大的那个,然后 LR 就变成了 LL,而 RL 就变成了 RR

    然后这题就做完了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    const ll MAXN=2e5+51;
    ll n,tot,x,y,swp;
    vector<ll>v[MAXN],vg[2],g[2][2];
    char ch[MAXN]; 
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    int main()
    {
        scanf("%s",ch+1),n=strlen(ch+1);
        for(register int i=1;i<=n;i++)
        {
            x=ch[i]=='R',vg[x^1].empty()?vg[x^1].push_back(++tot):(void)1;
            y=vg[x^1].back(),v[y].push_back(i);
            vg[x^1].pop_back(),vg[x].push_back(y);
        }
        printf("%d
    ",tot-1);
        for(register int i=1;i<=tot;i++)
        {
            g[v[i].size()&1][ch[v[i].back()]=='R'].push_back(i);
        }
        if(!g[0][0].empty()&&!g[0][1].empty()&&g[1][0].empty()&&g[1][1].empty())
        {
            x=g[0][0].back(),y=g[0][1].back();
            v[x].back()<v[y].back()?1:(swap(x,y),swp=1);
            v[x].push_back(v[y].back()),v[y].pop_back();
            g[0][0].pop_back(),g[0][1].pop_back(),swp?swap(x,y):(void)1;
            g[1][0].push_back(y),g[1][1].push_back(x);
        }
        if(g[1][0].size()!=g[1][1].size())
        {
            x=g[1][1].size()>g[1][0].size();
        }
        else
        {
            x=g[0][0].size()>g[0][1].size();
        }
        while(!g[0][x^1].empty())
        {
            for(register int i:v[g[0][x^1].back()])
            {
                printf("%d ",i);
            }
            g[0][x^1].pop_back();
        }
        while(!g[1][x].empty())
        {
            for(register int i:v[g[1][x].back()])
            {
                printf("%d ",i);
            }
            g[1][x].pop_back();
            while(!g[0][x].empty())
            {
                for(register int i:v[g[0][x].back()])
                {
                    printf("%d ",i);    
                }
                g[0][x].pop_back();
            }
            x^=1;
        }
    }
    
  • 相关阅读:
    (Bug修复)C#爬虫,让你不再觉得神秘
    C#高级特性(反射)
    Linux 宝塔部署 ASP.NET Core 应用
    WPF 的内部世界(Binding)
    渗透攻击红队内网靶场
    销量最优解
    遗传算法实现旅行商问题求解
    用java手写了个JSON解析&生成器
    Vue项目里面用a标签下载本地文件
    20192422李俊洁 实验六 Metasploit攻击渗透实践
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13733909.html
Copyright © 2020-2023  润新知