• 三个朋友


    https://loj.ac/problem/2823

    题目描述

      给出一个字符串(U),求满足条件的字符串(S)使其复制一遍再插入一个字符后的字符串为(U)

    思路

      由于插入过一个字符,所以我们可以进行一次扫描,每次扫描时将这个字符去掉,把去掉后字符串分成长度相等的两段,再比较这两段是否完全相同即可。如果暴力枚举看是否相同肯定会(T)飞,我们考虑使用字符串(Hash),求出两段的(Hash)值比较是否相等即可。需要注意的有两点:(①)把字符串取出时注意对进制转换;(②)有可能会存在多个相等的(S),它们不算重复。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    const ull p=47;
    char s[2000005];
    ull sum[2000005],power[2000005];
    int main() 
    {
    //    freopen("aa.txt","r",stdin);
        int n;
        scanf("%d",&n);
        scanf(" %s",s+1);
        if(n%2==0){printf("NOT POSSIBLE");return 0;}
        int len=(n-1)/2;
        power[0]=1;
        for(int i=1;i<=n;i++)
        {
            sum[i]=sum[i-1]*p+s[i]-'A';
            power[i]=power[i-1]*p;
        }
        ull ans=0,k=0,l=0;
        bool f=1;
    //    cout<<sum[4]<<endl;
        for(int i=1;i<=n;i++)
        {
            if(i<=len+1)
            {
                ull s1=sum[i-1]*power[len-i+1]+(sum[len+1]-sum[i]*power[len-i+1]);
                ull s2=sum[n]-sum[n-len]*power[len];
                if(s1==s2)
                {
                    ans++;
                    if(ans==1)k=s1,l=i;
                    else if(k!=s1)f=0;
                }
    //            cout<<i<<' '<<s1<<' '<<s2<<' '<<ans<<endl;
            }
            else
            {
                ull s1=sum[len];
                ull s2=(sum[i-1]-sum[len]*power[i-len-1])*power[len*2-i+1]+sum[n]-sum[i]*power[n-i];
                if(s1==s2)
                {
                    ans++;
                    if(ans==1)k=s1,l=i;
                    else if(k!=s1)f=0;
                }
    //            cout<<i<<' '<<s1<<' '<<s2<<' '<<ans<<endl;
            }
        }
    //    cout<<ans<<' '<<l<<endl;
        if(ans==1||(ans>1&&f))
        {
            if(l<=len+1)
                for(int i=n-len+1;i<=n;i++)
                    putchar(s[i]);
            else
                for(int i=1;i<=len;i++)
                    putchar(s[i]);
        }
        else if(ans==0)
            printf("NOT POSSIBLE");
        else printf("NOT UNIQUE");
        return 0;
    }
    
  • 相关阅读:
    Linux命令-网络命令:netstat
    Linux命令-网络命令:traceroute
    Linux命令-网络命令:lastlog
    Linux命令-网络命令:last
    mongodb3.4 安装及用户名密码设置
    MySQL表名不区分大小写的设置方法
    数据库设计中的四个范式
    dubbo本地调试直连
    com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1169 > 1024)
    Linux服务器时间同步
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11766977.html
Copyright © 2020-2023  润新知