HDU 1867 A + B for you again (水·KMP)

题目链接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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43768644/article/details/94411920
今日推荐