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

10 篇文章 0 订阅
9 篇文章 0 订阅

题目链接

题意

给定两个字符串 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值