题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1867
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;
}