1 条题解
-
0
提供一个好想的思路( ̄︶ ̄*))。
思路
首先两个字符串 同构当且仅当其可以被表示为 ( 均为字符串, 表示字符串拼接),不妨把两个字符串拼接起来,最终得到的串一定形如 ,对每个起始位置 跑两遍 KMP 求出 ,求出最大的 即可,至于翻转的情况,直接将 翻转一下与 拼接成一个新的字符串跑上面的算法即可。
时间复杂度 ,空间复杂度 。
#include <bits/stdc++.h> #define ll long long using namespace std; const int Maxn=6010; int kmp[Maxn],kmp1[Maxn],id[Maxn]; int n,m; char S[Maxn],T[Maxn],oth[Maxn],U[Maxn],V[Maxn]; int ret,bgn,bgm; inline void solve(int t){ int len=n+m; for(int i=1;i<=n;i++){ int p1=0,p2=0,tot=0; for(int j=1;j<=len;j++) kmp[j]=0,kmp1[j]=0; for(int j=i;j<=len;j++) U[j-i+1]=oth[j]; for(int j=i-1;j;j--) V[++tot]=oth[j],id[tot]=j; for(int j=len;j>=i;j--) V[++tot]=oth[j],id[tot]=j; for(int j=i+1;j<=len;j++){ while(p1 and U[p1+1]!=oth[j]) p1=kmp[p1+i-1]; if(U[p1+1]==oth[j]) ++p1; kmp[j]=p1; } for(int j=2;j<=tot;j++){ while(p2 and V[p2+1]!=V[j]) p2=kmp1[id[p2]]; if(V[p2+1]==V[j]) ++p2; kmp1[id[j]]=p2; } for(int j=n+1;j<=len;j++){ int mx1=min(min(n-i+1,j-n),kmp[j]); int mx2=min(min(i-1,len-j),kmp1[j+1]); if(mx1+mx2>ret){ ret=mx1+mx2; if(t) bgn=n-(i+mx1-1)+1,bgm=j-n-mx1+1; else bgn=i-mx2,bgm=j-n-mx1+1; } } } } int main(){ scanf("%s%s",S+1,T+1); n=strlen(S+1),m=strlen(T+1); for(int i=1;i<=n;i++) oth[i]=S[i]; for(int i=1;i<=m;i++) oth[i+n]=T[i]; solve(0); for(int i=1;i<=n;i++) oth[i]=S[n-i+1]; solve(1); printf("%d\n%d %d",ret,bgn-1,bgm-1); return 0; }
- 1
信息
- ID
- 10581
- 时间
- 1500ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者