# HDU 1876 A + B for you again（KMP）

Problem Description
Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.

Input
For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.

Output
Print the ultimate string by the book.

Sample Input
asdf sdfg asdf ghjk

Sample Output
asdfg asdfghjk

https://blog.csdn.net/baodream/article/details/79943459

#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>

using namespace std;

#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)

const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e6+5;

string str,mo;
int Next[N];

void Get_next()
{
int len=mo.length();
int j=-1;
Next[0]=-1;
int i=0;
while(i<len)
{
while(j!=-1&&mo[i]!=mo[j])
j=Next[j];
Next[++i]=++j;
}
}

int KMP()
{
int len = str.length();
int molen = mo.length();
int i = 0, j = 0;
while(i<len)
{
while(j!=-1&&str[i]!=mo[j])
j = Next[j];
++i;
++j;
}
if(j==0||j==-1)
return 0;
return j;
}

int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
std::ios::sync_with_stdio(false);
while(cin>>str>>mo)
{
Get_next();
int cnt1 = KMP();

string t = str;
str = mo;
mo = t;
Get_next();
int cnt2 = KMP();   //把第二个字符串放前面匹配

int cnt = cnt2;
if(cnt1>cnt2)      //如果第一种方法前后匹配得更多，则交换回来
{
cnt = cnt1;
t = str;
str = mo;
mo = t;
}
else if(cnt1==cnt2)   //一样多的话，看字典序谁更小
{
if(mo<str)
{
t = str;
str = mo;
mo = t;
}
}
cout<<str;
for(int i=cnt;i<mo.length();i++)
cout<<mo[i];
cout<<endl;
}
return 0;
}