• Codeforces 1178E. Archaeology


    传送门

    首先一定有解,考虑归纳法证明

    首先 $n<=3$ 时显然

    考虑 $n=4$ 时,那么因为 $s[1]!=s[2],s[3]!=s[4]$ ,并且 $s[i] in {a,b,c}$ 由鸽巢原理显然意味着 $s[1],s[2]$ 至少有一个等于 $s[3]$ 或 $s[4]$

    那么我们从中间往两边延伸,每左边两个就和右边两个组合,这样每四个位置就有两个位置会贡献回文字符,那么一定有解

    注意如果 $n mod 4=2$ 或者 $n mod 4=3$ 时最后会剩下几个不能组成左边两个右边两个,那么我们回文长度搞成奇数即可(中间先选择一个作为回文中心)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e6+7;
    int n;
    char s[N];
    vector <int> ans;
    void work(int l,int r)
    {
        for(; l>=2&&r<=n-1; l-=2,r+=2)
        {
            vector <int> cnt[3];
            cnt[s[l-1]-'a'].push_back(l-1);
            cnt[s[r+1]-'a'].push_back(r+1);
            cnt[s[l]-'a'].push_back(l);
            cnt[s[r]-'a'].push_back(r);
            for(int k=0;k<3;k++)
                if(cnt[k].size()>1)
                {
                    ans.push_back(cnt[k][0]),
                    ans.push_back(cnt[k][1]);
                    break;
                }
        }
    }
    int main()
    {
        scanf("%s",s+1); n=strlen(s+1);
        int mid=1+n>>1;
        if(n%4) { ans.push_back(mid); work(mid-1,mid+1); }
        else work(mid,mid+1);
        sort(ans.begin(),ans.end());
        for(auto p: ans) printf("%c",s[p]);
        puts(""); return 0;
    }
  • 相关阅读:
    C#定时执行任务
    C#判断数据库是否可连接(PING)
    Excel之导入数据
    JQuery之杂项方法$.grep()
    .Net EF 之代码生成策略
    平台与WeLink深度融合技术汇总
    Host is not allowed to connect to this MySQL
    excel中过长的数字怎么筛选重复项
    oracle 函数大全
    WinXP添加TLS1.1、TLS1.2支持
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11612640.html
Copyright © 2020-2023  润新知