解题报告:给你两个字符串,让你连接起来,没有前后顺序,要求是长度最短优先,其次是字典序最小。这题我用的是KMP,做两次匹配,分别把第一次跟第二次输入的字符串放前面,然后比较两次得到的字符窜的长度和字典序。
1 #include<cstdio> 2 #include<cstring> 3 const int MAX = 200000+5; //因为如果两个加一起就有可能超出了,干脆开两倍的数组 4 int next[MAX]; 5 void get_next(const char *t) { 6 next[0] = -1; 7 int len = strlen(t); 8 int i = 0,j = -1; 9 while(i<len-1) { 10 if(j == -1 || t[i] == t[j]) { 11 i++; 12 j++; 13 next[i] = j; 14 } 15 else j = next[j]; 16 } 17 // next[0] = 0; // 将第一个next标记为-1,后面有用 18 } 19 void KMP(char *s,const char *t) { 20 get_next(t); 21 int len1 = strlen(s); 22 int len2 = strlen(t); 23 int i = 0,j = 0; 24 if(len1 > len2) 25 i = len1 - len2; 26 while(i < len1 && j<len2) { 27 if(j == -1||s[i] == t[j]) { //这里j==0和j==-1有区别,只有第一个才是-1 ,而0有很多个 28 i++; 29 j++; 30 } 31 else j = next[j]; 32 } 33 strcpy(s+len1,t+j); 34 } 35 36 int main() { 37 char T[MAX],S1[MAX],S2[MAX]; 38 while(scanf("%s%s",S1,S2)!=EOF) { 39 strcpy(T,S1); 40 KMP(S1,S2); 41 KMP(S2,T); 42 int len1 = strlen(S1); 43 int len2 = strlen(S2); 44 if(len1<len2) 45 printf("%s ",S1); 46 else if(len1>len2) 47 printf("%s ",S2); 48 else { 49 int flag = strcmp(S1,S2); 50 if(flag == 1) 51 printf("%s ",S2); 52 else printf("%s ",S1); 53 } 54 } 55 return 0; 56 }