题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1867
解题思路:KMP求可以去掉的最长循环节。正反都要,优先取短的,其次取字典序小的
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#include<string>
#include<iostream>
using namespace std;
const int N = 1e5+5;
string A,B;
string s;
string s1,s2;
int fail[N<<1];
int kmp()
{
fail[0] = -1;
for (int i=0,j=-1;i<s.length();){
if (j==-1||s[i]==s[j]){
i++;j++;
fail[i] = j;
}
else j = fail[j];
}
//printf("相同前后缀=%d\n",fail[s.length()]);
int now = s.length();
int len = min(A.length(),B.length());
while (fail[now]>len) now = fail[now];
return fail[now];
}
int main()
{
std::ios::sync_with_stdio(false);
while (cin >> A >> B){
//*******************************************
///A+B 求-> B+(去掉前缀)A
s = A;
s = s + B;//cout << s << endl;
int cut = kmp();
//printf("cut=%d\n",cut);
s1 = B;
for (int i=cut;i<A.length();i++)
s1.push_back(A[i]);
//****************************************
///B+A 求-> A + (去掉前缀)B
s = B;
s = s + A; //cout << s << endl;
cut = kmp();
//printf("cut=%d\n",cut);
s2 = A;
for (int i=cut;i<B.length();i++)
s2.push_back(B[i]);
//-------------------------------------------
if (s1.length()==s2.length()){
if (s1<=s2) cout << s1 << endl;
else cout << s2 <<endl;
}
else {
if (s1.length()<s2.length()) cout << s1 << endl;
else cout << s2 <<endl;
}
}
return 0;
}