最近研究合并组合,稍微总结一下,以后继续补充:
http://acm.hdu.edu.cn/showproblem.php?pid=1867
标题意大,给定两个字符串,若一个字串的前缀是另一个字串的后缀,则可以合并。要求合并后的字串首先要尽可能短,然后要按字典序尽可能的短;
路思:两个字串按先后顺序不同可以有两种组合,对与每种组合失掉KMP法算的next数组,next[len]就是两个字串可以合并的度长;
#include<iostream> #include<stdio.h> #include<string.h> #include<stdlib.h> #define min(a,b) a<b?a:b using namespace std; char s[200005],a[100005],b[100005]; int next[200005]; int KMP(int len,int n) { int i=0,j=-1; next[0]=-1; while(i<n){ if(j==-1||s[i]==s[j]){ i++; j++; next[i]=j; } else j=next[j]; } while(next[n]>len){ n=next[n]; } return next[n]; } int main() { while(scanf("%s%s",a,b)!=EOF){ int len1=strlen(a); int len2=strlen(b); strcat(strcpy(s,a),b); int ans1=KMP(min(len1,len2),len1+len2);//第一个参数为可以合并的大最度长 strcat(strcpy(s,b),a); int ans2=KMP(min(len1,len2),len1+len2); int i; if(ans1>ans2){ for(i=0;i<len2;i++)printf("%c",b[i]); for(i=ans1;i<len1;i++)printf("%c",a[i]); } else if(ans2>ans1){ for(i=0;i<len1;i++)printf("%c",a[i]); for(i=ans2;i<len2;i++)printf("%c",b[i]); } else{ if(strcmp(a,b)>0){ for(i=0;i<len2;i++)printf("%c",b[i]); for(i=ans1;i<len1;i++)printf("%c",a[i]); } else{ for(i=0;i<len1;i++)printf("%c",a[i]); for(i=ans2;i<len2;i++)printf("%c",b[i]); } } printf("\n"); } return 0; }
文章结束给大家分享下程序员的一些笑话语录: 姿势要丰富,经常上百度!