hdu - 1867 - A + B for you again
Posted Been You
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu - 1867 - A + B for you again相关的知识,希望对你有一定的参考价值。
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
- int KMP(char s[], char t[])
- {
- get_next(t);
- int i = 0, j = 0, l1, l2;
- l1 = strlen(s);
- l2 = strlen(t);
- while(i < l1 && j < l2){//结束条件
- if(j == 0 && s[i] != t[j])
- i++;
- 10. else if(j > 0 && s[i] != t[j])
- 11. j = Next[j-1];
- 12. else{
- 13. i++;
- 14. j++;
- 15. }
- 16. }
- 17. if(i == l1)//处理返回值
- 18. return j;
- 19. return 0;
20. }
但是这是卡不住刚才说的数据的,因为它的两次KMP的值都会是0,输出是“asdfwedfdf”,但它的正确输出应该是“asdfwedf”才对。
其中的原因只要理解了KMP的处理过程就不难想出来了。
话不多说了直接上代码吧,聪明的你一看就懂。
AC代码:
[cpp] view plain copy
- #include<stdio.h>
- #include<string.h>
- #define N 100010
- int Next[N];
- char s1[N], s2[N];
- 10.
- 11.
12. void get_next(char str[])
13. {
- 14. int i = 1, j = 0, len;
- 15. len = strlen(str);
- 16. while(i < len){
- 17. if(j == 0 && str[i] != str[j]){
- 18. Next[i] = 0;
- 19. i++;
- 20. }
- 21. else if(j > 0 && str[i] != str[j])
- 22. j = Next[j-1];
- 23. else{
- 24. Next[i] = j+1;
- 25. i++;
- 26. j++;
- 27. }
- 28. }
29. }
30. int KMP(char s[], char t[])
31. {
- 32. get_next(t);
- 33. int i = 0, j = 0, l1, l2;
- 34. l1 = strlen(s);
- 35. l2 = strlen(t);
- 36. while(i < l1){//这里必须要把s串跑完,不然会造成bug,漏掉情况。虽然按一般的形式写也能AC
- 37. if(j == 0 && s[i] != t[j])
- 38. i++;
- 39. else if(j > 0 && s[i] != t[j])
- 40. j = Next[j-1];
- 41. else{
- 42. i++;
- 43. j++;
- 44. }
- 45. }
- 46. return j;
47. }
- 48.
- 49.
50. int main()
51. {
- 52. int k, k1, k2;
- 53. while(~scanf("%s%s", s1, s2)){
- 54. k1 = KMP(s1, s2);
- 55. k2 = KMP(s2, s1);
- 56. if(k1 == k2){
- 57. if(strcmp(s1, s2) == -1)
- 58. printf("%s%s\n", s1, s2+k1);
- 59. else
- 60. printf("%s%s\n", s2, s1+k1);
- 61. }
- 62. else if(k1 > k2)
- 63. printf("%s%s\n", s1, s2+k1);
- 64. else
- 65. printf("%s%s\n", s2, s1+k2);
- 66. }
- 67. return 0;
68. }
以上是关于hdu - 1867 - A + B for you again的主要内容,如果未能解决你的问题,请参考以下文章
hdu - 1867 - A + B for you again
HDU1867 A + B for you again(KMP)
HDU 1867 A + B for you again ----KMP