ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[bzoj3916] friends

2020-03-03 23:04:32  阅读:264  来源: 互联网

标签:power int long Sample ull bzoj3916 include friends


Description

有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.

Input

第一行一个数N,表示U的长度.

第二行一个字符串U,保证U由大写字母组成

Output

输出一行,若S不存在,输出"NOT POSSIBLE".若S不唯一,输出"NOT UNIQUE".否则输出S.

Sample Input1

7
ABXCABC

Sample Output1

ABC

Sample Input2

6
ABCDEF

Sample Output2

NOT POSSIBLE

Sample Input3

9
ABABABABA

Sample Output3

NOT UNIQUE

Hint

对于100%的数据 2<=N<=2000001

题解

这题很显然是一道字符串\(Hash\),但是有一些坑点

由于我将若S不唯一看成了若插入的位置不唯一,创造了我的首\(WA\)

接着,我却将每次可以的\(S\)记录下来,导致时间代价太大,造成了我的首\(TLE\),\(TLE\)代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;

typedef unsigned long long ull;
const int L=2000005,E=100007;
char s[L],Out[L];
int l,Ans;
ull power[L],h[L];

void PutIn(int id)//超时的关键
{
    if(id<=l/2)
    {
        for(int i=1;i<=l/2;++i) Out[i]=s[i+l/2+1];
        return;
    }
    for(int i=1;i<=l/2;++i) Out[i]=s[i];
}

int Check(int id)//超时的关键
{
    if(id<=l/2)
    {
        for(int i=1;i<=l/2;++i)
            if(Out[i]!=s[i+l/2+1]) return 1;
        return 0;
    }
    for(int i=1;i<=l/2;++i)
        if(Out[i]!=s[i]) return 1;
    return 0;
}

int main()
{
    scanf("%d\n%s",&l,s+1);
    if(l%2==0) {puts("NOT POSSIBLE");goto end;}
    power[0]=1;
    for(int i=1;i<=l;++i) power[i]=power[i-1]*E;
    for(int i=1;i<=l;++i) h[i]=h[i-1]*E+s[i];
    for(int i=1;i<=l;++i)
    {
        if(i<=l/2)
        {
            if((h[l/2+1]-h[i]*power[l/2+1-i]+h[i-1]*power[l/2+1-i])
            ==(h[l]-h[l/2+1]*power[l/2]))
                if(!Ans) {Ans=i;PutIn(i);}
                else if(Check(i))
                        {puts("NOT UNIQUE");goto end;}
        }
        else
        {
            if(h[l/2]
            ==(h[l]-h[i]*power[l-i]+h[i-1]*power[l-i]-h[l/2]*power[l-l/2-1]))
                if(!Ans) {Ans=i;PutIn(i);}
                else if(Check(i))
                        {puts("NOT UNIQUE");goto end;}
        }
    }
    if(!Ans) puts("NOT POSSIBLE");
    else
    {
        for(int i=1;i<=l/2;++i) printf("%c",Out[i]);
        putchar('\n');
    }
    end:
    return 0;
}

注意到上面代码中造成\(TLE\)的罪魁祸首,如果我们能够\(O(1)\)来比较的话那么问题不就迎刃而解了吗

字符串\(Hash\)的作用是什么?

将字符转化成数,从而方便的计算与比较大小,(大雾

\(My~Code\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;

typedef unsigned long long ull;
const int L=2000005,E=100007;
char s[L];
int l,Ans;
ull power[L],h[L],hAns;

int main()
{
    scanf("%d\n%s",&l,s+1);
    if(l%2==0) {puts("NOT POSSIBLE");goto end;}
    power[0]=1;
    for(int i=1;i<=l;++i) power[i]=power[i-1]*E;
    for(int i=1;i<=l;++i) h[i]=h[i-1]*E+s[i];
    for(int i=1;i<=l;++i)
    {
        if(i<=l/2)
        {
            if((h[l/2+1]-h[i]*power[l/2+1-i]+h[i-1]*power[l/2+1-i])
            ==(h[l]-h[l/2+1]*power[l/2]))//此处的过程需要用草稿纸或大脑子
                if(!Ans) Ans=i,hAns=h[l]-h[l/2+1]*power[l/2];
                else if(h[l]-h[l/2+1]*power[l/2]!=hAns)
                    {puts("NOT UNIQUE");goto end;}
        }
        else
        {
            if(h[l/2]
            ==(h[l]-h[i]*power[l-i]+h[i-1]*power[l-i]-h[l/2]*power[l-l/2-1]))
                if(!Ans) Ans=i,hAns=h[l/2];
                else if(h[l/2]!=hAns)
                    {puts("NOT UNIQUE");goto end;}
        }
    }
    if(!Ans) puts("NOT POSSIBLE");
    else
    {
        if(Ans<=l/2)
        {
            for(int i=l/2+2;i<=l;++i) printf("%c",s[i]);
            putchar('\n');
        }
        else
        {
            for(int i=1;i<=l/2;++i) printf("%c",s[i]);
            putchar('\n');
        }
    }
    end:
    return 0;
}

标签:power,int,long,Sample,ull,bzoj3916,include,friends
来源: https://www.cnblogs.com/hihocoder/p/12405400.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有