HDU 1867 KMP

题意:

求str1 的最长后缀与 str2 的最长前缀。使得 str1+str2  的长度最小,并且字典序最小(str1和str2可以互换)

 

题解:

kmp的p数组的含义:p[i]表示以i为结尾的字符串最多和开头匹配的个数。也正是这道题求解的关键、

具体做法就是将两个字符串合并处理求一下p数组就好了~

ps:合并的时候中间一定要加“分隔符”(比如:#,@之类的~),否则会有惊喜。。。

abcbcbca bcbcbc    对拍了半天才发现这个bug。。。

 

View Code
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <cstdio>

 5 #include <algorithm>

 6 

 7 #define N 2001000

 8 

 9 using namespace std;

10 

11 int lena,lenb,lenc;

12 int p[N];

13 char str1[N],str2[N],c[N];

14 

15 inline void getp()

16 {

17     p[1]=0;

18     for(int i=2,len=0;i<=lenc;i++)

19     {

20         while(len>0&&c[i]!=c[len+1]) len=p[len];

21         if(c[i]==c[len+1]) len++;

22         p[i]=len;

23     }

24 }

25 

26 inline int getlen(char a[],char b[])

27 {

28     lena=strlen(a+1);

29     lenb=strlen(b+1);

30     lenc=lena+lenb+1;

31     for(int i=1;i<=lenb;i++) c[i]=b[i];

32     c[1+lenb]='#';

33     for(int i=1;i<=lena;i++) c[i+lenb+1]=a[i];

34     getp();

35     return p[lenc];

36 }

37 

38 inline void go()

39 {

40     int len1=getlen(str1,str2);

41     int len2=getlen(str2,str1);

42     if(len1==len2)

43     {

44         if(strcmp(str1+1,str2+1)<0) printf("%s%s",str1+1,str2+len1+1);

45         else printf("%s%s",str2+1,str1+len2+1);

46     }

47     else if(len1<len2) printf("%s%s",str2+1,str1+len2+1);

48     else printf("%s%s",str1+1,str2+len1+1);

49     puts("");

50 }

51 

52 int main()

53 {

54     while(scanf("%s%s",str1+1,str2+1)!=EOF) go();

55     return 0;

56 }

 

 

你可能感兴趣的:(HDU)