https://ac.nowcoder.com/acm/problem/13253
思路
因为我们只要保证所给t是s的字串,即kmp模板;
我们的重点是求s,t中最大的进制,最有可能使得t是s的字串,所以s要抓缓存最大的进制。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
string s,t;
int nex[1000010],n;
char p='0',to[16]={'0','1','2','3','4','5','6',
'7','8','9','A','B','C','D','E','F'}; //用来查找t的最大和s的进制转换
void change()
{
int num=0;
for(int i=0;i<16;i++)
{
if(to[i]==p)
{
num=i+1; //进制要+1
break;
}
}
int tem;
for(int i=1;i<=n;i++)
{
string now;
tem=i;
while(tem) //逆序求出进制
{
now+=to[tem%num];
tem/=num;
}
reverse(now.begin(),now.end());
s+=now;
}
}
void get_next()
{
int j=0,k=-1;
nex[0]=-1;
int len=t.length();
while(j<len)
{
if(p<t[j])p=t[j];
if(k==-1||t[k]==t[j])
{
k++,j++;
if(t[k]==t[j])
nex[j]=nex[k];
else nex[j]=k;
}
else
k=nex[k];
}
if(p>'F'||p<'0'||(p>'9'&&p<'A'))puts("no");
else
change();
}
int kmp()
{
int j=0,k=0;
int lens=s.length(),lent=t.length();
while(j<lens&&k<lent)
{
if(k==-1||s[j]==t[k])
{
k++,j++;
}
else
k=nex[k];
}
if(k==lent)printf("yes");
else printf("no");
}
int main()
{
scanf("%d",&n);
cin>>t;
get_next();
kmp();
}
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
string s;
int nex[1000010],num[1000010];
void get_next()
{
int j=0,k=-1;
nex[0]=-1;
int len=s.length();
while(j<len)
{
if(k==-1||s[k]==s[j])
{
k++,j++;
nex[j]=k;
}
else
k=nex[k];
}
}
int main()
{
cin>>s;
get_next();
int len=s.length();
for(int i=2;i<len;i++) //为什么遍历nex数组查找与nex[len]相同的个数的数字呢?
num[nex[i]]++; //因为可能字符串全是aaaaaaaaa,这样就找不到
int k=nex[len]; //统计每个nex的数据
while(k)
{
if(num[k]) //存在与后缀相等的
{
for(int i=0;i<k;i++)
cout << s[i];
return 0;
}
k=nex[k]; //回溯,针对aaaa这种情况
}
puts("Just a legend");
}