1. 程式人生 > >A + B for you again(HDU-1867)(最長公共字首和字尾)

A + B for you again(HDU-1867)(最長公共字首和字尾)

A + B for you again

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

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 題目大意:
給出兩個字串合併出一個長度與字典序最小的字串,且給出的兩個串分別為這個合併字串的字首與字尾。

題目分析:

注意是先按照長度最小,然後再按照字典序最小輸出。

注意題目要求的是最短的字串能包含所給的兩個字串,這裡的包含一定是前一部分或後一部分包含,不能中間包含。

程式碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N=100000+999;
int nex[N];
char s1[N],s2[N];
void make_next(int n,char *a)
{
    int i,j;
    nex[0]=0;
    for(i=1,j=0; i<n ; i++)
    {
        while(j>0&&a[i]!=a[j])
            j=nex[j-1];
        if(a[i]==a[j])
            j++;
        nex[i]=j;
    }
}
int KMP(int n,int m,char *a,char *b)
{
    make_next(m,b);
    int i,j;
    for(i=0,j=0; i<n; i++)
    {
        while(j>0&&a[i]!=b[j])
            j=nex[j-1];
        if(a[i]==b[j])
            j++;
        if(j==m)
            break;
    }
    if((i==n-1&&j==m)||i==n) //只能是模式串匹配到主串結束
        return j;
    return 0;
}
int main()
{
    while(scanf(" %s %s",s1,s2)!=EOF)
    {
        int len1=strlen(s1);
        int len2=strlen(s2);
        int b=KMP(len1,len2,s1,s2);
        int a=KMP(len2,len1,s2,s1);
        if(b>a) //s2的字首與s1的字尾匹配較長
        {
            printf("%s%s\n",s1,s2+b);
        }
        else if(a>b)//s1的字首與s2的字尾匹配較長
        {
            printf("%s%s\n",s2,s1+a);
        }
        else //如果匹配長度相等則看字典序從小到大
        {
            if(strcmp(s1,s2)<0) printf("%s%s\n",s1,s2+b);
            else printf("%s%s\n",s2,s1+a);
        }
    }
    return 0;
}