题意:
给你两个字符串a,b相加 a+b,合并a的后缀和b的前缀 得到ab
在 将 b a 相加 b+a 合并b的后缀和a的前缀 得到ba
在先比较ab ba长度 短的优先 如果长度相同 按字典树小的优先
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5+10;
char fa[maxn], c[maxn];
int nextval[maxn], flag;
void get_nextval(char *b, int len2)
{
int i = 0, j = -1;
nextval[i] = -1;
while(i < len2)
{
if(j == -1 || b[i] == b[j])
{
if(b[++i] != b[++j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
void kmp_search(char *a, char *b, int len1, int len2)
{
memset(c, 0, sizeof(c));
get_nextval(b, len2);
int i = 0, j = 0;
while(i < len1 && j <= len2)//j == len2 保证b串的前缀和后缀相交 而不是中间相交就结束了
{
if(j == -1 || a[i] == b[j]) ++i, ++j;
else j = nextval[j];
}
i = i-j;
for(int k = 0; k < i; k++) c[k] = a[k];//a 的后缀前面的一部分。
strcat(c, b);
if(!flag) strcpy(fa, c), flag = 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
char a[maxn], b[maxn];
while(scanf("%s%s", a, b) != EOF)
{
memset(fa, 0, sizeof(fa));
flag = 0;
int len1 = strlen(a);
int len2 = strlen(b);
kmp_search(a, b, len1, len2);
kmp_search(b, a, len2, len1);
int lenc = strlen(c);
int lenfa = strlen(fa);
if(lenc < lenfa) printf("%s\n", c);
else if(lenc > lenfa) printf("%s\n", fa);
else if(lenc == lenfa)
{
if(strcmp(c, fa)<0) printf("%s\n", c);
else printf("%s\n", fa);
}
}
}
hdu 1867 A + B for you again
最新推荐文章于 2024-05-15 16:44:19 发布