HDU 1876 A + B for you again(KMP)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baodream/article/details/79951981

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


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页