HDU 1876 A + B for you again(KMP)

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值