1. 程式人生 > >hdu - 1867 - A + B for you again

hdu - 1867 - A + B for you again

selected blank tar tro .net ini rip res second

A + B for you again

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


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

題意概括:

先確定s1和s2相同的部分並輸出s1中相同部分之前的串、相同部分和s2中相同部分之後的串。

解題分析:

水題。進行兩次KMP,然後讀懂題意就可以了。主要就是判斷s1的後綴和s2的前綴相等,然後輸出s1相同部分之前的字

符、相同部分和s2相同部分之後的字符。因為在對s1和s2進行KMP時,它倆都可以作為文本串和模板串,所以要進行兩

次KMP。當兩次KMP返回的值不相等時,就要用值大的那個(KMP返回的值是兩個字符串前後綴相等的長度)。如果兩

個返回值相等再按字母表順序輸出(這裏就包含了兩個串不相等的情況了)。

需要註意的是“asdfwedf”, “df” 這組數據如果用一般的KMP是卡不住這組數據的(雖然OJ中沒有這組數據)。

通常KMP中循環的結束是當兩個字符串有一個結束就結束循環,然後判斷一下文本串是否跑完處理一下返回值就可以了。如下:

[cpp] view plain copy

print?

  1. int KMP(char s[], char t[])
  2. {
  3. get_next(t);
  4. int i = 0, j = 0, l1, l2;
  5. l1 = strlen(s);
  6. l2 = strlen(t);
  7. while(i < l1 && j < l2){//結束條件
  8. if(j == 0 && s[i] != t[j])
  9. i++;
  10. 10. else if(j > 0 && s[i] != t[j])
  11. 11. j = Next[j-1];
  12. 12. else{
  13. 13. i++;
  14. 14. j++;
  15. 15. }
  16. 16. }
  17. 17. if(i == l1)//處理返回值
  18. 18. return j;
  19. 19. return 0;

20. }

但是這是卡不住剛才說的數據的,因為它的兩次KMP的值都會是0,輸出是“asdfwedfdf”,但它的正確輸出應該是“asdfwedf”才對。

其中的原因只要理解了KMP的處理過程就不難想出來了。

話不多說了直接上代碼吧,聰明的你一看就懂。

AC代碼:

[cpp] view plain copy

print?

  1. #include<stdio.h>
  2. #include<string.h>
  3. #define N 100010
  4. int Next[N];
  5. char s1[N], s2[N];
  6. 10.
  7. 11.

12. void get_next(char str[])

13. {

  1. 14. int i = 1, j = 0, len;
  2. 15. len = strlen(str);
  3. 16. while(i < len){
  4. 17. if(j == 0 && str[i] != str[j]){
  5. 18. Next[i] = 0;
  6. 19. i++;
  7. 20. }
  8. 21. else if(j > 0 && str[i] != str[j])
  9. 22. j = Next[j-1];
  10. 23. else{
  11. 24. Next[i] = j+1;
  12. 25. i++;
  13. 26. j++;
  14. 27. }
  15. 28. }

29. }

30. int KMP(char s[], char t[])

31. {

  1. 32. get_next(t);
  2. 33. int i = 0, j = 0, l1, l2;
  3. 34. l1 = strlen(s);
  4. 35. l2 = strlen(t);
  5. 36. while(i < l1){//這裏必須要把s串跑完,不然會造成bug,漏掉情況。雖然按一般的形式寫也能AC
  6. 37. if(j == 0 && s[i] != t[j])
  7. 38. i++;
  8. 39. else if(j > 0 && s[i] != t[j])
  9. 40. j = Next[j-1];
  10. 41. else{
  11. 42. i++;
  12. 43. j++;
  13. 44. }
  14. 45. }
  15. 46. return j;

47. }

  1. 48.
  2. 49.

50. int main()

51. {

  1. 52. int k, k1, k2;
  2. 53. while(~scanf("%s%s", s1, s2)){
  3. 54. k1 = KMP(s1, s2);
  4. 55. k2 = KMP(s2, s1);
  5. 56. if(k1 == k2){
  6. 57. if(strcmp(s1, s2) == -1)
  7. 58. printf("%s%s\n", s1, s2+k1);
  8. 59. else
  9. 60. printf("%s%s\n", s2, s1+k1);
  10. 61. }
  11. 62. else if(k1 > k2)
  12. 63. printf("%s%s\n", s1, s2+k1);
  13. 64. else
  14. 65. printf("%s%s\n", s2, s1+k2);
  15. 66. }
  16. 67. return 0;

68. }

hdu - 1867 - A + B for you again