#include <stdio.h> #include <string.h> int next[100005]; void build_next(char str[]) { int i=0,j=-1; next[0] = -1; int len2=strlen(str); while (i < len2) { if (j==-1 || str[i] == str[j]) { i++; j++; if (str[i] != str[j]) { next[i] = j; } else next[i] = next[j]; } else j = next[j]; } } int KMP(char str1[],char str2[]) { int len1=strlen(str1); int len2=strlen(str2); build_next(str2); int i=0,j=0,cnt=0; while (i < len1 &&j <len2) { if (j==-1 || str1[i] == str2[j]) { i++; j++; } else j = next[j]; } if(i==len1) return j; return 0; } int main() { int N,n,i,m; char str1[100005],str2[100005]; while (~scanf("%s%s",str1,str2)) { // gets(str2); //gets在这里不行,有空格 n=KMP(str1,str2); m=KMP(str2,str1); //还要考虑模式串的问题,两个字符串都可以作为模式串,所以要有两个KMP函数 if(m == n) { if(strcmp(str1,str2)>0) { printf("%s",str2); printf("%s\n",str1+n); } else { printf("%s",str1); printf("%s\n",str2+n); } } else if(n>m) { printf("%s",str1); printf("%s\n",str2+n); } else { printf("%s",str2); printf("%s\n",str1+m); } } return 0; }
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
分析:主要是看清题目的意思。
asdf 和 sdfg asdf的后缀和sdfg的前缀有相同的sdf 所以在相加之后等于: asdfg
asdf ghjk 之间没有共同的前后缀,所以加起来等于 asdfghjk
还要考虑模式串的问题,两个字符串都可以作为模式串,所以要有两个KMP函数
题目最后说guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.
输出的时候还要满足前面的字符串的字典序要小于后面的字典序
比如 asdfa 和 asdf 首先 n=m。其次因为 strcmp(str1,str2) >0 所以要先输出str2 再输出 str1+n;
asdf sdfg asdf ghjk
asdfg asdfghjk
HDU 1867 A + B for you again (KMP)
原文地址:http://blog.csdn.net/xinwen1995/article/details/46123889