Friends

Friends

题目描述

给定一个字符串S,先将字符串S复制一次(变成双倍快乐),得到字符串T,然后在T中插入一个字符,得到字符串U。
给出字符串U,重新构造出字符串S。
所有字符串只包含大写英文字母。

输入描述

第一行一个整数N,表示字符串U的长度。 N<=2e6+1
第二行一个长度为N的字符串,表示字符串U。

输出描述

一行一个字符串,表示字符串S。
特别地:
如果字符串无法按照上述方法构造出来,输出NOT POSSIBLE;
如果字符串S不唯一,输出NOT UNIQUE。

样例

input1

7
ABXCABC

output1

ABC

input2

6
ABCDEF

output2

NOT POSSIBLE

input3

9
ABABABABA

output3

NOT UNIQUE

思路

由题可知若字符串U满足条件,则从字符串U中抽取一个字符后,得到的为两个字符串S。我们只需要枚举这个字符,然后判断能否得到两个相同的字符串即可。可采用hash来求解。
当N为偶数时,显然不满足。接下来我们枚举抽取字符的位置i,当i恰好位于中间时,左右都为字符串S;当i位于左边时,显然字符串右半部分等于S;当i位于右边时,字符串左半部分等于S。后两种情况i会把一个S分成两部分,我这里也就把它拆解成两部分比较hash值。
然后是处理S不唯一的情况。由以上分析易知S要么等于字符串左半部分l,要么等于右半部分r。在遍历过程中如能得到l和r都有满足条件的情况,只需比较l和r就行。如果不相同,说明S不唯一。

代码

#include <iostream>
#include <string>
using namespace std;
#define MAXN 2000005

typedef unsigned long long ull;
ull Hash[MAXN], power[MAXN];
const int b = 27;

int main(void) {
    int n; cin>>n;
    string s; cin>>s; s = " "+s;
    power[0] = 1;
    for (int i = 1; i <= n; ++i) power[i] = power[i - 1] * b;
    for (int i = 1; i <= n; ++i) Hash[i] = Hash[i - 1] * b + (ull)(s[i] - 'A' + 1);
    if (n % 2 == 0) {
        puts("NOT POSSIBLE");
        return 0;
    } else {
        bool l = false, r = false;
        for (int i = 1; i <= n; ++i) {
            if (i == n / 2 + 1) {
                if (Hash[n / 2] == Hash[n] - Hash[n / 2 + 1] * power[n / 2]) l = true;
            } else if (i <= n / 2) {
                if (Hash[i - 1] == Hash[n / 2 + 1 + i - 1] - Hash[n / 2 + 1] * power[i - 1] && Hash[n / 2 + 1] - Hash[i] * power[n / 2 - i + 1] == Hash[n] - Hash[n / 2 + 1 + i - 1] * power[n / 2 - i + 1]) r = true;
            } else if (i > n / 2 + 1) {
                if (Hash[i - 1] - Hash[n / 2] * power[i - n / 2 - 1] == Hash[i - n / 2 - 1] && Hash[n] - Hash[i] * power[n - i] == Hash[n / 2] - Hash[n / 2 - n + i] * power[n - i]) l = true;
            }
        }
        if(l && r){
            if(s.substr(1,n/2) == s.substr(n/2+2,n/2)) cout<<s.substr(1,n/2);
            else puts("NOT UNIQUE");
        }
        else if(l) cout<<s.substr(1,n/2);
        else if(r) cout<<s.substr(n/2+2,n/2);
        else puts("NOT POSSIBLE");
    }
    return 0;
}

第一篇博客,意思一下,哈哈^_^

海到无边天作岸,山登绝顶我为峰
原文地址:https://www.cnblogs.com/Fiona0726/p/12764502.html