hdu 1867 A + B for you again

题意:
给你两个字符串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);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值