知识点:哈希算法
题意:
给定字符串S,对字符串S+S,插入一个数,得到T,现在给你T,让你求出可能的S字符串,根据情况,答案分为,输出唯一的S,或输出“NOT POSSIBLE”或“NOT UNIQUE”。
思路:
比较暴力的一个题,但是拿到的第一瞬间没有思路,是因为对于hash的理解还不到位,以及这道题调了非常久的时间。但是这是非常不应该的,错误在于。if(n&1==0)这个判断没有打括号(正解:if((n&1)==0) ),切记啊,记不得优先级就得狂打括号!空耗好几个小时。暴力枚举x的位置,然后再根据x的位置和字符串中位的关系,构建前一半的hash和后一半的hash,判断是否相等。注意,根据题意,多种方案得到的同一个S,也是唯一的解。
题解代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#define rep(i,l,n) for(int i=(l);i<=(n);++i)
#define ll long long
#define ull unsigned long long
#define N 2000010
using namespace std;
ull h[N],p[N]={1},l,r,mid,base=707;
map <ull,int> mp;
char s[N];
int ans[100],cnt,len,n;
void shash()
{
rep(i,1,n)
{
h[i]=h[i-1]*base+(ull)s[i];
p[i]=p[i-1]*base;
}
return ;
}
void pd(ull l,ull r,int i)
{
if(l==r&&mp[l]==0)
{
ans[++cnt]=i;
mp[l]=1;
}
return;
}
int main()
{
scanf("%d",&n);
if((n&1)==0){puts("NOT POSSIBLE");return 0;}
scanf("%s",s+1);
len=n/2;
shash();
rep(i,1,n)
{
if(i<=len)
{
l=h[i-1],mid=h[len+1]-h[i]*p[len+1-i],r=h[n]-h[n-len]*p[len];
l=l*p[len+1-i]+mid;
pd(l,r,i);
}
else if(i==len+1)
{
l=h[i-1],r=h[n]-h[i]*p[len];
pd(l,r,i);
}
else
{
l=h[len],r=h[n]-h[i]*p[n-i],mid=h[i-1]-h[len]*p[i-len-1];
r=mid*p[n-i]+r;
pd(l,r,i);
}
if(cnt>1)break;
}
if(cnt==1)
{
int j=1;
while(j<=len)
{
if(j==ans[cnt])++j,len++;
printf("%c",s[j]);
++j;
}
}
else if(cnt==0)
{
puts("NOT POSSIBLE");
}
else
{
puts("NOT UNIQUE");
}
// system("pause");
return 0;
}
posted on
浙公网安备 33010602011771号