思路:
若N是偶数,则S不存在。
若N是奇数,去除一个字母,看剩下的前后两个字串是否相等。
因26个大写字母,故B取29.
该题的难点在于拼接字符串。
有人提出,采用除运算,将尾部字母去除,请注意,这是不行的,在模运算中,除法是不能轻易用的,否则,干嘛要学乘法逆元。
如何求解某段子串,请看哈希值生成过程
字符串ABCDEFG
哈希值生成过程
ah[1] A
ah[2] AB
ah[3] ABC
ah[4] ABCD
ah[5] ABCDE
ah[6] ABCDEF
ah[7] ABCDEFG
去除某个字母,剩下两子串生成过程
(A)BCDEFG
BCD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
BCD 等价于ah[4]-a[1]*n[3]
A(B)CDEFG
ACD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
ACD 等价于ah[1]*n[2]+ah[4]-ah[2]*n[2]
AB(C)DEFG
ABD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
ABD 等价于ah[2]*n[1]+ah[4]-ah[3]*n[1]
......
ABCDEF(G)
ABC DEF子串生成:
ABC 等价于ah[3]
DEF 等价于ah[6]-ah[3]*n[3]
文火慢炖:
删除的字母位置在i,i在前半段
删除的字母位置整个字串的正中央
删除的字母位置在i,i在后半段
上述3种情况的讨论,是靠着数据一点一点的算出来的,提供几组数据如下:
7
XABCABC
7
AXBCABC
7
ABXCABC
7
ABCXABC
7
ABCAXBC
7
ABCABXC
7
ABCABCX
上述数据均属出
ABC
关键测试数据
输入数据:
7
AAAAAAA
输出数据:
AAA
洛谷中若WA#50#53#59#61#64
请注意题目中有这样一段话:
如果从 U 得到的 S 不是唯一的,输出 NOT UNIQUE
也就是说,如果能得到唯一的解,即使有多种删去可能,也要输出答案,而不是NOT UNIQUE!!!!!
上面的关键测试数据 就是上述说法的具体实施。
AC代码:
ybt
通过
测试点 | 结果 | 内存 | 时间 |
测试点1 | 答案正确 | 340KB | 1MS |
测试点2 | 答案正确 | 336KB | 1MS |
测试点3 | 答案正确 | 340KB | 0MS |
测试点4 | 答案正确 | 340KB | 0MS |
测试点5 | 答案正确 | 340KB | 0MS |
测试点6 | 答案正确 | 344KB | 0MS |
测试点7 | 答案正确 | 340KB | 1MS |
测试点8 | 答案正确 | 340KB | 0MS |
测试点9 | 答案正确 | 340KB | 0MS |
测试点10 | 答案正确 | 340KB | 0MS |
测试点11 | 答案正确 | 340KB | 0MS |
测试点12 | 答案正确 | 344KB | 0MS |
测试点13 | 答案正确 | 344KB | 0MS |
测试点14 | 答案正确 | 340KB | 0MS |
测试点15 | 答案正确 | 344KB | 0MS |
测试点16 | 答案正确 | 340KB | 0MS |
测试点17 | 答案正确 | 340KB | 0MS |
测试点18 | 答案正确 | 340KB | 0MS |
测试点19 | 答案正确 | 340KB | 0MS |
测试点20 | 答案正确 | 340KB | 0MS |
测试点21 | 答案正确 | 344KB | 0MS |
测试点22 | 答案正确 | 340KB | 0MS |
测试点23 | 答案正确 | 340KB | 0MS |
测试点24 | 答案正确 | 340KB | 0MS |
测试点25 | 答案正确 | 332KB | 0MS |
测试点26 | 答案正确 | 340KB | 0MS |
测试点27 | 答案正确 | 340KB | 0MS |
测试点28 | 答案正确 | 340KB | 0MS |
测试点29 | 答案正确 | 344KB | 0MS |
测试点30 | 答案正确 | 340KB | 0MS |
测试点31 | 答案正确 | 340KB | 0MS |
测试点32 | 答案正确 | 348KB | 0MS |
测试点33 | 答案正确 | 336KB | 0MS |
测试点34 | 答案正确 | 340KB | 0MS |
测试点35 | 答案正确 | 340KB | 0MS |
测试点36 | 答案正确 | 344KB | 0MS |
测试点37 | 答案正确 | 336KB | 0MS |
测试点38 | 答案正确 | 336KB | 0MS |
测试点39 | 答案正确 | 344KB | 0MS |
测试点40 | 答案正确 | 344KB | 0MS |
测试点41 | 答案正确 | 344KB | 0MS |
测试点42 | 答案正确 | 340KB | 0MS |
测试点43 | 答案正确 | 336KB | 0MS |
测试点44 | 答案正确 | 380KB | 1MS |
测试点45 | 答案正确 | 368KB | 1MS |
测试点46 | 答案正确 | 372KB | 1MS |
测试点47 | 答案正确 | 376KB | 1MS |
测试点48 | 答案正确 | 368KB | 1MS |
测试点49 | 答案正确 | 336KB | 0MS |
测试点50 | 答案正确 | 368KB | 1MS |
测试点51 | 答案正确 | 376KB | 1MS |
测试点52 | 答案正确 | 376KB | 1MS |
测试点53 | 答案正确 | 364KB | 1MS |
测试点54 | 答案正确 | 368KB | 1MS |
测试点55 | 答案正确 | 33532KB | 79MS |
测试点56 | 答案正确 | 33532KB | 78MS |
测试点57 | 答案正确 | 33532KB | 78MS |
测试点58 | 答案正确 | 33532KB | 78MS |
测试点59 | 答案正确 | 33528KB | 78MS |
测试点60 | 答案正确 | 2284KB | 12MS |
测试点61 | 答案正确 | 33532KB | 80MS |
测试点62 | 答案正确 | 30220KB | 35MS |
测试点63 | 答案正确 | 30216KB | 70MS |
测试点64 | 答案正确 | 30220KB | 70MS |
测试点65 | 答案正确 | 28008KB | 32MS |
LOJ
LUOGU
AC代码如下:
#include <cstdio>
#include <cstring>
#define maxn 2000010
#define B 29
#define ULL unsigned long long
using namespace std;
char a[maxn];
int an;
ULL ah[maxn],n[maxn],b=0;
int main(){
int N,i,j,tot,len,k=0;
scanf("%d%s",&N,a+1);
if(N%2==0){//N是偶数
printf("NOT POSSIBLE\n");
return 0;
}
an=strlen(a+1);
n[0]=1;
for(i=1;i<=an;i++)n[i]=n[i-1]*B;
ah[0]=0;
for(i=1;i<=an;i++)ah[i]=ah[i-1]*B+a[i]-'A'+1;
tot=0;
len=an/2;
for(i=1;i<=an/2;i++){//删除的字母位置在i,i在前半段
if(ah[an]-ah[an-len]*n[len]==ah[i-1]*n[len-(i-1)]+ah[len+1]-ah[i]*n[len-i+1]){//此行代码耗费心力
k=i,tot++;
if(!b)b=ah[an]-ah[an-len]*n[len];
else if(b!=ah[an]-ah[an-len]*n[len]){
printf("NOT UNIQUE\n");
return 0;
}
}
}
if(ah[len]==ah[an]-ah[an-len]*n[len]){//删除的字母位置整个字串的正中央
k=len+1,tot++;
if(!b)b=ah[len];
else if(b!=ah[len]){
printf("NOT UNIQUE\n");
return 0;
}
}
for(i=an/2+2;i<=an;i++){//删除的字母位置在i,i在后半段
if(ah[len]==(ah[i-1]-ah[len]*n[(i-1)-len])*n[an-i]+ah[an]-ah[i]*n[an-i]){//此行代码耗费心力
k=i,tot++;
if(!b)b=ah[len];
else if(b!=ah[len]){
printf("NOT UNIQUE\n");
return 0;
}
}
}
if(tot==0)printf("NOT POSSIBLE\n");
else{
if(k<=an/2+1){
for(i=an/2+2;i<=an;i++)printf("%c",a[i]);
printf("\n");
}else{//k>an/2+1
for(i=1;i<=an/2;i++)printf("%c",a[i]);
printf("\n");
}
}
return 0;
}
该题编码比较耗时的,对于哈希值的理解,是更上了一层楼了。此题必刷。