HDU 1867 A + B for you again kmp算法

来源:互联网 发布:mac 连不上appstore 编辑:程序博客网 时间:2024/06/05 19:30

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1867

题意:给定两个字符串,把一个字符串接在另一个字符串的后面,相接部位若有相同,则可以略去其中一个字符串的相同部分,输出拼接后最小长度的字符串,若有两种最小长度的字符串,输出字典序较小的那个

思路:可以用kmp匹配一个字符串的尾部和另一个字符串的首部相同的最大长度,然后交换两个字符串的次序,再来一次匹配,根据匹配出来的长度来决定把那个字符串放在前面

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100010;int nt[N];char s1[N], s2[N];void getnt(char s[]){    int i = 0, j = -1;    nt[0] = -1;    while(s[i])    {        if(j == -1 || s[i] == s[j])        {            i++, j++;            if(s[i] != s[j]) nt[i] = j;            else nt[i]= nt[j];        }        else j = nt[j];    }}int kmp(char s1[], char s2[]) //s1是目标串,s2是模式串{    getnt(s2);    int i = 0, j = 0;    while(s1[i])    {        if(j == -1 || s1[i] == s2[j])            i++, j++;        else j = nt[j];        if(j != -1 && !s2[j] && s1[i]) //s2匹配到末端时,要判断s1是不是末端,若不是末端,则令j跳转,若是末端,则保持j不变            j = nt[j];    }    return j;}int main(){    while(~ scanf("%s%s", s1, s2))    {        int l1 = kmp(s1, s2); //s1的尾部和s2的首部匹配的长度        int l2 = kmp(s2, s1); //s2的尾部和s1的首部匹配的长度        if(l1 > l2)        {            printf("%s", s1);            printf("%s", s2 + l1);        }        else if(l1 < l2)        {            printf("%s", s2);            printf("%s", s1 + l2);        }        else        {            if(strcmp(s1, s2) < 0)            {                printf("%s", s1);                printf("%s", s2 + l1);            }            else            {                printf("%s", s2);                printf("%s", s1 + l2);            }        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击