题意:
给定两个字符串a和b,现在要将a和b相加,a+b相加规则为找出a最长的后缀等于b的等长前缀,之后结果为a的前面部分+相等部分+b的后面部分,例如:asdf+sdfg=asdfg。相加的时候也可以b+a,输出相加后长度最小的,若存在两者长度相等,则输出字典树较小的。
题解:
标准的KMP算法应用,用一个串匹配另一个串,被匹配串的最后的一位匹配值就是最长的相等部分了。然后用这种方法求得a+b和b+a,之后选择小的输出。
代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <map> #include <vector> using namespace std; const int maxn=1e5+10; char a[maxn],b[maxn],c[maxn]; int f[maxn]; void getFail(char *a,int *f,int n) { int i,j; f[0]=f[1]=0; for(i=1;i<n;i++) { j=f[i]; while(j&&a[i]!=a[j])j=f[j]; f[i+1]=a[i]==a[j]?j+1:0; } } int find(char *a,char *b,int *f) { int i,j=0,n,m; n=strlen(a); m=strlen(b); getFail(b,f,m); for(i=0;i<n;i++) { while(j&&a[i]!=b[j])j=f[j]; if(a[i]==b[j])j++; } return j; } int main() { while(scanf("%s%s",a,b)!=EOF) { int i,j,k,p,q; p=find(a,b,f); q=find(b,a,f); if(p>q||p==q&&strcmp(a,b)<0) { k=p; printf("%s",a); for(i=k;b[i]!='\0';i++)printf("%c",b[i]); printf("\n"); } else { k=q; printf("%s",b); for(i=k;a[i]!='\0';i++)printf("%c",a[i]); printf("\n"); } } return 0; }