hdu-4300(字符串hash)
题目链接:传送门
参考文章:传送门
思路:
(1)对字符串进行翻译,求出s1(未翻译),s2(已翻译)字符串,并分别对s1,s2进行hash操作。
(2)比较s1的后x位和s2的前x位的hash值,求出最长的长度的中间位置。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100100; char s1[maxn],s2[maxn],ss[maxn]; int fy[maxn]; typedef unsigned long long ULL; ULL hash1[maxn],hash2[maxn],pre[maxn],base=133; ULL getl(int l,int r,ULL arr[]) { return arr[r]-arr[l-1]*pre[r-l+1]; } void Init() { pre[0]=1; for(int i=1;i<maxn;i++) pre[i]=pre[i-1]*base; } int main(void) { int T,i; scanf("%d",&T); Init(); while(T--) { scanf("%s%s",ss,s1+1); int l=strlen(ss),len=strlen(s1+1); for(i=0;i<l;i++) fy[ss[i]-'a']=i; for(i=1;i<=len;i++) { s2[i]=fy[s1[i]-'a']+'a'; } for(hash1[0]=0,hash2[0]=0,i=1;i<=len;i++) { hash1[i]=hash1[i-1]*base+(ULL)s1[i]; hash2[i]=hash2[i-1]*base+(ULL)s2[i]; } //cout<<s2+1<<endl; int ans=len; for(i=len;i<len*2;i++) //最长长度一定是偶数, { if(i&1) continue; //判断偶数 int t1=i/2; int t2=len-t1; ULL a1=getl(1,t2,hash2); ULL a2=getl(len-t2+1,len,hash1); if(a1==a2) { ans=t1;break; } } for(i=1;i<=ans;i++) printf("%c",s1[i]); for(i=1;i<=ans;i++) printf("%c",s2[i]); printf("\n"); } return 0; }