zoukankan      html  css  js  c++  java
  • BZOJ 3916: [Baltic2014]friends


    BZOJ 3916: [Baltic2014]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 Input

    Sample Input1:
    7
    ABXCABC


    Sample Input2:

    6
    ABCDEF

    Sample Input3:

    9
    ABABABABA

    Sample Output

    Sample Output1:

    ABC

    Sample Output2:

    NOT POSSIBLE

    Sample Output3:

    NOT UNIQUE

    HINT

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

    思路 :

      对整个字符串进行hash,枚举插入字符位置,分三种情况讨论:在前半段, 在中间,在后半段, 分别把枚举到的剔除,把两段hash接到一起,与另外半串对比 若hash相同则存下来,等到下一次出现相同的时候判断是否重复,重复输出NOT UNIQUE ,如果一直没有ans 输出NOT POSSIBLE 如果所有答案的hash是相同的,在出答案的时候记录插入字符的位置,直接输出另外半段字符串即可 代码如下

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char s[2100001];
    unsigned int h1[2100001],mi[2100001];
    unsigned int hav[2100001],tot;
    const int p = 1313131;
    int idx,n;
    unsigned int creat(int l,int r) {
        if(l>r)return 0;
        return h1[r]-h1[l-1]*mi[r-l+1];
    }
    bool check(int x) {
        if(x<=idx) {
            unsigned int x1 = creat(1,x-1);
            unsigned int x2 = creat(x+1,idx+1);
            unsigned int x3 = creat(idx+2,n);
            (x1*=mi[idx-x+1])+=x2;
            if(x1==x3){hav[++tot]=x1;return 1;}
        }
        else if(x==idx+1)  {
            unsigned int x1 = creat(1,x-1);
            unsigned int x3 = creat(x+1,n);
            if(x1==x3) 
            {hav[++tot]=x1;return 1;}
        }
        else {
            unsigned int x1 = creat(1,idx);
            unsigned int x2 = creat(idx+1,x-1);
            unsigned int x3 = creat(x+1,n);
            (x2*=mi[n-x])+=x3;
            if(x2==x1) {hav[++tot]=x1;return 1;}
        }
        return 0;
    }
    void print(int x) {
        if(x==1) {
            for(int i=1;i<=n/2;i++) {
                putchar(s[i]);
            }
        }
        else {
            for(int i=n/2+2;i<=n;i++) {
                putchar(s[i]);
            }
        }
    }
    int main() {
       // freopen("2.in","r",stdin);
        scanf("%d%s",&n,s+1);
        idx=(n-1)/2;
        /*puts("NOT UNIQUE");
        return 0;*/
        if(!(n&1)) {
            puts("NOT POSSIBLE");
            return 0;
        }
        mi[0]=1;
        int i,cnt=0;
        for(i=1;i<=n;i++) {
            mi[i]=mi[i-1]*p;
            h1[i]=h1[i-1]*p+s[i];
        }
        /*for(i=1;i<=n;i++) {
            if(h1[i])printf("%d
    ",i);
        }*/
        int tmp=0;
        for(i=1;i<=n;i++) {
            if(check(i)) 
            {
                //printf("%d
    ",i);
                cnt++,tmp=i;
            }
    			
        }
        sort(hav+1,hav+tot+1);
        int amt=0;
        for(i=1;i<=tot;i++) {
            if(hav[i]!=hav[i-1])amt++;
        }
        if(cnt>1&&amt>1) {
            puts("NOT UNIQUE");
        }
        else if(!cnt) {
            puts("NOT POSSIBLE");
        }
        else {
            if(tmp<=idx+1) {
                print(2);
            }
            else {
                print(1);
            }
        }
    }
    

     欢迎来原博客看看 >原文链接<

  • 相关阅读:
    Unity3D ShaderLab 立方体图的反射遮罩
    Unity3D ShaderLab 简单的立方体图反射
    Unity3D ShaderLab 各向异性高光
    Unity3D ShaderLab 使用贴图对模型的高光进行遮罩
    Unity3D ShaderLab 使用BlinnPhong高光类型
    Unity3D ShaderLab 创建自定义高光类型
    Unity3D ShaderLab 基础的高光实现
    Unity3D ShaderLab法线贴图
    Unity3D ShaderLab压缩混合纹理贴图
    Java几种建立实例的方法
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9079100.html
Copyright © 2011-2022 走看看