• [水]悠悠碧波


    [水]悠悠碧波

    题目描述

    帕秋莉掌握了一种水属性魔法

    这种魔法可以净化黑暗

    帕秋莉发现对于一个黑暗的咒语s,可以使用这个水元素魔法净化它,净化的咒语是一个最长的字符串t,t满足以下条件:

    它是s的前缀

    它是s的后缀

    除前缀和后缀外,它还在s中出现过至少一次

    既然你都学会了,那么净化的工作就交给你了!

    输入描述

    一行字符串 S,代表黑暗咒语

    输出描述

    一个字符串 T,表示满足条件的最长净化咒语

    样例输入

    tqrwantoacthisproblembutqristooweaktodoitqr
    

    样例输出

    tqr
    

    备注

    对于60%的数据,s长度≤100
    对于100%的数据,s长度≤100,000
    保证存在可行的净化咒语

    题解

    直接对字符串hash,从大到小枚举结果字符串的长度,比较前缀后缀的hash值,并在字符串中搜索是否存在相同的子字符串,验证即可。

    代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=111111,mp=123;
    ll hh[maxn],pp[maxn];
    int n;
    char str[maxn];
    
    ll gethh(int l,int r)
    {
        return hh[r]-hh[l-1]*pp[r-l+1];
    }
    
    bool chack(int len)
    {
        for(int i=2;i<=n-len;i++){
            if(gethh(i,i+len-1)==gethh(1,len)){
                return true;
            }
        }
        return false;
    }
    
    int main()
    {
        cin>>str+1;
        n=strlen(str+1);
        pp[0]=1;
        for(int i=1;i<=n;i++){
            hh[i]=hh[i-1]*mp+str[i];
            pp[i]=pp[i-1]*mp;
        }
        for(int i=n-1,j=2;i>0;i--,j++){
            if(gethh(1,i)==gethh(j, n)){
                if(chack(i)){
                    for(int k=1;k<=i;k++)
                        cout<<str[k];
                    cout<<endl;
                    break;
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SVN tags使用
    switch case执行顺序
    excel 15位身份证转18位
    .net core options 依赖注入的方式
    DICOM 相关概念了解
    Dicom文件基本操作
    asp.net core 3 使用nlog日志组件,使用$ {basedir}保存位置不对,记录下怎么解决
    asp.net core 动态更新 appsetting.json方法
    asp.net core appsetting.json 绑定读取
    centos 安装 nginx 及配置 的坑
  • 原文地址:https://www.cnblogs.com/LeafLove/p/13296211.html
Copyright © 2020-2023  润新知