HDU 1867 A + B for you again (kmp的运用)

A + B for you again

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9063    Accepted Submission(s): 2194


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
 

Author
Wang Ye
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1711  1866  3336  1277  1358 

题目意思很简单,不过有点坑的地方在于最后输出的字符串要是最短的并且字典序最小的,

用kmp去找两个字符串相互重叠(a的后缀和b的前缀或者b的前缀和a的后缀)的部分长度是多少,如果a和b 相互重叠的部分一样长,就比较a和b谁的字典序小,然后输出小的那个就好了.


#include <iostream>
#include<string>
#include<cstring>
using namespace std;
string a,b;
int nexts[100005];
void getnext(string b)
{
    memset(nexts,0,sizeof(nexts));
    nexts[0]=-1;
    int k=-1;
    int i=0;
    int len=b.size();
    while(i<len)
    {
        if(k==-1||b[i]==b[k])
        {
            ++i,++k;
            nexts[i]=k;
        }
        else
            k=nexts[k];
    }
}

int kmp(string a,string b)
{
    getnext(b);
    int cnt=0;
    int j=0;
    int i=0;
    int lena=a.size();
    int lenb=b.size();
    while(i<lena)
    {
        if(j==-1||a[i]==b[j])
            ++i,++j;
        else
            j=nexts[j];
    }
    return j; // 返回匹配到的最大的长度
}


int main()
{

    while(cin>>a>>b)
    {
        int len1=kmp(a,b);
        int len2=kmp(b,a);
        if(len1==len2){
            if(a<b)
                cout<<a<<b.c_str()+len1<<endl; //巧妙的一点:string 转char* 类型后,直接加上可重叠的长度即可输出重叠后的字符
            else
                cout<<b<<a.c_str()+len2<<endl;
        }
        else
        if(len1>len2){            //最后的结果长度尽可能短.
            cout<<a<<b.c_str()+len1<<endl;
        }
        else
            cout<<b<<a.c_str()+len2<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_35866463/article/details/80680346
今日推荐