您的位置:首页 > 大数据 > 人工智能

HDU 1867 A + B for you again 字符串拼接 kmp

2017-09-20 20:26 489 查看

题目链接

题意

给定两个字符串 A,B,可以拼成 AB 也可以拼成 BA,拼接时前缀与后缀的相同部分在拼接成的字符串中只出现一次。

要求输出最短的且字母序最小的字符串。

这道题关键是要读懂题意= =

思路

基本同HDU 2594 Simpsons’ Hidden Talents 两字符串前缀与后缀的最长公共部分.

直接用 fail 数组就完了。

Code

#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
typedef long long LL;
char T[maxn], P[maxn], s[maxn], s1[maxn], s2[maxn];
int f[maxn], len;
bool big(char* s1, char* s2, int len) {
for (int i = 0; i < len; ++i) {
if (s1[i] > s2[i]) return true;
else if (s1[i] < s2[i]) return false;
}
return false;
}
void getfail() {
f[0] = f[1] = 0;
for (int i = 1; i < len; ++i) {
int j = f[i];
while (j && s[i] != s[j]) j = f[j];
f[i+1] = s[i] == s[j] ? j+1 : 0;
}
}
int cat(char* T, char* P) {
strcpy(s, T), strcat(s, "*"), strcat(s, P);
getfail();
return f[len];
}
void work() {
int n = strlen(T), m = strlen(P);
len = n+1+m;
int l1 = cat(T, P), l2 = cat(P, T);
if (l1 > l2) strcpy(P+m-l1, T), printf("%s\n", P);
else if (l1 < l2) strcpy(T+n-l2, P), printf("%s\n", T);
else {
strcpy(s1, T), strcpy(s1+n-l1, P);
strcpy(s2, P), strcpy(s2+m-l2, T);
if (big(s1, s2, n+m-l1)) printf("%s\n", s2);
else printf("%s\n", s1);
}
}
int main() {
while (scanf("%s%s", T, P) != EOF) work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: