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.
asdf sdfg asdf ghjk
asdfgasdfghjk
题目意思:给你两个串str1,str2,将这两个串按规定合并,规定就是如果str1的一个后缀等于str2的一
前缀,就可以省略其中一个,例如asdf和sdfg,asdf的后缀sdf等于sdfg的前缀sdf,那么省略
其中一个得到asdfg。还有一个最重要的一点(一开始我忽略了,一直wa)就是如果得到的串长
度相同就按字典序小的输出。
解题思路:一道kmp的题目,两个串比较,一直比到一个串的末尾,然后记录此时匹配的串的长的,这个长
度就是重合需要省略的串的长度。
注意:这个题需要比较两次,str和str1一次,str1和str一次,取最短的,长度相同取字典序
小的。比较字典序用strcmp(str,str1),返回值小于0的就是str字典序小,反之成立。
#include<iostream> #include<cstring> using namespace std; int const maxn=100005; char str[maxn],str1[maxn]; int next1[maxn]; int len,len1; void sign(char *str1) { int i,j; next1[0]=-1; i=-1,j=0; int len1=strlen(str1); while(j<len1) { if(i==-1||str1[i]==str1[j]) { i++; j++; next1[j]=i; } else { i=next1[i]; } } } int kmp(char *str,char *str1) { int m=0,n=0; int len=strlen(str); int len1=strlen(str1); sign(str1); while(m<len) { if(n==-1||str[m]==str1[n]) { m++; n++; } else { n=next1[n]; } } return n; } int main() { while(~scanf("%s",str)) { scanf("%s",str1); int sign1=kmp(str,str1); int sign2=kmp(str1,str); if(sign1==sign2) { if(strcmp(str,str1)<0) //用strcmp比较字典序 { cout<<str<<str1+sign1<<endl; } else { cout<<str1<<str+sign2<<endl; } } else if(sign1>sign2) { cout<<str<<str1+sign1<<endl; } else { cout<<str1<<str+sign2<<endl; } } return 0; }