盗CA爷的题,学习了最小表示法,最后发现CA爷不是写的这个算法。
但不管了。
最小表示法大致是维护两个指针ij且i!=j 把它们向后扫,直到st[i+k]!=st[j+k] 然后将st较大的那个指针移到x+k+1,如果两个指针相等,任取一个加一。 注意是一个循环字符串,在k=l时退出。
因为vijos上没有JUDGE_ONLINE 这个宏,wa了半天。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1e9
#define eps 1e-10
#define md
#define N 2000010
using namespace std;
char st1[N],st2[N];
int get(char st[],int l)
{
int i=0,j=1;
while (i<l&&j<l)
{
int k=0;
while (k<l&&st[i+k]==st[j+k]) k++;
if (k==l) break;
if (st[i+k]>st[j+k]) i=i+k+1;
else j=j+k+1;
if (i==j) j++;
// printf("%d %d\n",i,j);
} //printf("\n");
return min(i,j);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in","r",stdin); freopen("data.out","w",stdout);
#endif
scanf("%s%s",st1,st2);
int l1=strlen(st1),l2=strlen(st2);
for (int i=l1;i<(l1<<1);i++) st1[i]=st1[i-l1]; st1[l1<<1]='\0';
for (int j=l2;j<(l2<<1);j++) st2[j]=st2[j-l2]; st2[l2<<1]='\0';
//printf("%s %s\n",st1,st2);
if (l1!=l2)
{
printf("No\n");
}
else
{
int a=get(st1,l1),b=get(st2,l2);
//printf("%d %d\n",a,b);
bool ok=1;
for (int i=a,j=b,l=1;l<=l1;l++,i++,j++)
{
if (st1[i]!=st2[j]) { ok=0; break;}
}
if (ok)
{
printf("Yes\n");
for (int i=a,l=1;l<=l1;l++,i++)
{
putchar(st1[i]);
}
printf("\n");
}
else printf("No\n");
}
return 0;
}