题目链接: hdu 1867 A + B for you again
题意:有两个串,让你求两个串的和,也就是头或尾部的公共串相重合,实现两个串的相加,若两个串头尾重合的长度相同,则按字典序输出。
因为没有说哪一个为模式串,哪一个为匹配串,所以两个串的不同顺序都要考虑,进行两次查询公共长度。
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 111111
using namespace std;
void GetNext(char p[],int Next[])
{
int j=0,k=-1,plen;
plen=strlen(p);
Next[0]=-1;
while(j<plen)
{
if(k==-1||p[j]==p[k]) j++,k++,Next[j]=k;
else k=Next[k];
}
}
int kmp(char s[],char p[],int Next[])
{
GetNext(p,Next);
int i=0,j=0;
int slen=strlen(s);
while(i<slen)
{
if(j==-1||s[i]==p[j]) i++,j++;
else j=Next[j];
}
return j;//返回匹配的长度
}
int main()
{
char s[maxn],p[maxn];
int Next[maxn];
while(~scanf("%s%s",s,p))
{
fill(Next,Next+maxn,0);
int len1=kmp(s,p,Next);
int len2=kmp(p,s,Next);
if(len1==len2) //当两次的公共长度相同时,按字典序输出
{
if(strcmp(s,p)>0) printf("%s%s\n",p,s+len1);
else printf("%s%s\n",s,p+len1);
}
else if(len1>len2) printf("%s%s\n",s,p+len1);//第一次的长度长,则先输出第一个串
else printf("%s%s\n",p,s+len2);
}
return 0;
}