hdu 1867 A + B for you again

hdu 1867 点击打开链接 

题意:求最小亲和串,即给出两个字符串s1,s2,求一个最小亲和串 s,即包含s1,也包含s2.但需注意的是此题若s1为asdf,  s2为sd,  最小亲和串为 asdfsd.

规则:1.长度越短优先

            2.字典序越小优先

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<string>
using namespace std;
const int maxn=100005;
char a[maxn],b[maxn];
int next[maxn];
void get_next(char *a)
{
    int i=0,j=-1;
    next[0] = -1;
    while( a[i] )
    {
        if(j == -1 || a[i]==a[j])
        {
            if(a[++i] != a[++j]){
                next[i] = j;
            }
            else next[i] = next[j];
        }
        else j = next[j];
    }
}
int KMP(char *a,char *b)///用a的前缀去匹配b的后缀,返回匹配好的a的最大前缀。。
{
    int i=0,j=0;
    get_next(a);
    while( b[j] ){
        if(i == -1 || a[i] == b[j]) ++i,++j;
        else i = next[i];
    }
    return i;
}
int main()
{
    while(scanf("%s%s",a,b)!=EOF)
    {
        int k1=KMP(a,b);
        int k2=KMP(b,a);
        if(k1==k2){
            if(strcmp(a,b)<=0)
                printf("%s%s\n",a,b+k2);
            else 
                printf("%s%s\n",b,a+k1);
        }
        else if(k1>k2)
            printf("%s%s\n",b,a+k1);
        else printf("%s%s\n",a,b+k2);
    }
    return 0;
}


你可能感兴趣的:(hdu 1867 A + B for you again)