• UPC8173【 哈希和哈希表】Three Friends


    【 哈希和哈希表】Three Friends

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 67  解决: 11
    [提交] [状态] [命题人:admin]

    题目描述

    Three friends like to play the following game. The first friend chooses a string S. Then the second friend constructs a new string T that consists of two copies of the string S. finally, the third friend inserts one letter at the beginning, the end or somewhere inside the string T, thereby creating a string U.
    You are given the string U and your task is to reconstruct the original string S.

    输入

    The first line of the input contains N(2 ≤ N ≤ 2000001), the length of the final string U. The string U itself is given on the second line. It consists of N uppercase English letters (A, B, C, . . . , Z).

    输出

    Your program should print the original string S. However, there are two exceptions:
    1.If the final string U could not have been created using the above procedure, you should print NOT POSSIBLE.
    2.If the original string S is not unique, you should print NOT UNIQUE.

    样例输入

    7
    ABXCABC
    

    样例输出

    ABC


    刚开始写字符串哈希,这题卡了好一会儿,我觉得主要是对于哈希的理解吧,做法很好想,枚举每一位假设这个是加入的字符,然后判断剩下的两半字符串是否相等就行,
    用字符串哈希之后的哈希数表判断可以O(1)判断。
    问题的关键在于如何正确进行两个字符串的拼接。
    这里给出规律,如果是拼接在主串中所占范围为1到len的子串a和范围为(len+2)到n的子串b,h[n]-h[len+1]*f[n-len-1]+h[len]*f[n-len]
    可以看出来,实际上就是将串a的tmp幂次转到和串b相同,也就是乘上相差的tmp的幂次,然后进行加减。(就这么理解吧暂时)

    贴本题AC代码,反复改了好久。这题还有个坑点是注意重复的情况,记得开个map用vis标记一下。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long unsigned llu;
    typedef long long ll;
    const int N=2e6+5;
    const int mod=1e9+7;
    const int tmp=31;
    string a;
    int n;
    unsigned long long  f[N];
    unsigned long long  h[N];
    ll la;
    ll ans[N],k;
    map<llu,int>vis;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        f[0]=1;
        for(int i=1; i<=N-1; i++)
            f[i]=f[i-1]*tmp;
        cin>>n;
        cin>>a;
        la=a.size();
        if(la%2==0)
        {
            cout<<"NOT POSSIBLE"<<endl;
            return 0;
        }
        memset(h,0,sizeof h);
        for(int i=1;i<=la;i++)h[i]=h[i-1]*tmp+a[i-1]-'A'+1;
      //  cout<<h[3]<<endl;
        int pos=-1;
        llu len=(la>>1);
        for(int i=1; i<=la; i++)
        {
            llu v1,v2;
            if(i<=len)
            {
                v1=h[i-1]*f[len-i+1]+h[len+1]-h[i]*f[len-i+1];
                v2=h[la]-h[len+1]*f[la-len-1];
            }
            else if(i==len+1)
            {
                v1=h[len];
                v2=h[la]-h[len+1]*f[la-len-1];
            }
            else
            {
                v1=h[len];
                v2=h[la]-h[i]*f[la-i]+(h[i-1]-h[len]*f[i-1-len])*f[la-i];
            }
           // cout<<v1<<" "<<v2<<endl;
            if(v1==v2)
            {
                if(pos!=-1&&!vis[v1])
                {
                    cout<<"NOT UNIQUE"<<endl;
                    return 0;
                }
                else pos=i,vis[v1]=true;
            }
        }
        if(pos==-1)
        {
            cout<<"NOT POSSIBLE"<<endl;
            return 0;
        }//cout<<pos<<endl;
        for(int i=0; i<n; i++)
        {
            if(i==pos-1)
                continue;
            if(len==0)
                break;
            cout<<a[i];
            len--;
        }
        return 0;
    }
    

      






                                                                                                                                             
  • 相关阅读:
    面向对象---类与类之间的关系
    面向对象二 成员
    面向对象一
    内置函数二---作业
    内置函数⼆
    学习python的第十三天-----函数作业
    学习python的第十二天
    学习python的第十二天---函数的进阶
    学习python的第是一天————函数进阶的作业
    学习python的第十天------函数的进阶
  • 原文地址:https://www.cnblogs.com/liuquanxu/p/11409717.html
Copyright © 2020-2023  润新知