A + B for you again hdu 1867

题目:

Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.

Input

For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.

Output

Print the ultimate string by the book.

Sample Input

asdf sdfg
asdf ghjk

Sample Output

asdfg
asdfghjk

 

题意:

寻找两个字符串的前后缀最大相等部分(第一个字符串的前缀第二个字符串的后缀相等,或者第二个字符按串的前缀或者后缀,选取两者中最长输出),输出一个串不相等部分+相等部分+另一个串的不相等部分。当两个字符串完全不相等时间,按长短输出,长度短的在前,长度较长的在后。长度相等时,按字典序较小的在前,较大的在后输出。

 

思路:

分别计算字符串a+b和b+a的最长公共前后缀max1,max2;

如果max1>max2,则输出b,和a除了公共部分的字符;

如果max1<max2,则输出a,和b除了公共部分的字符;

如果max1=max2,比较形成字符串的字典序,输出字典序小的;

 

代码:

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
int nextt[210000],n;
void getnext(string s)
{
    int i=0,j=-1;
    nextt[0]=-1;
    while(i<n)
    {
        if(j==-1||s[i]==s[j])
        {
            i++;j++;
            nextt[i]=j;
        }
        else
            j=nextt[j];
    }
}
int main()
{
    string a,b,s;
    while(cin>>a>>b)
    {
        s=a+b;
        n=s.length();
        int l1=a.length();
        int l2=b.length();
        memset(nextt,0,sizeof(nextt));
        getnext(s);
        /*for(int i=0;i<=n;i++)
            printf("%d\n",nextt[i]);*/
        int max1=0,max2=0;
        int minn=min(l1,l2);
        max1=nextt[n];
        if(max1>minn)//注意 aaaaa a  这类情况
            max1=minn;
        memset(nextt,0,sizeof(nextt));
        getnext(b+a);
        max2=nextt[n];
        if(max2>minn)//注意 aaaaa a  这类情况
            max2=minn;
        if(max1>max2)
        {
            cout<<b;
            int l=a.length();
            for(int i=max1;i<l;i++)
                printf("%c",a[i]);
            cout<<endl;
        }
        else if(max1<max2)
        {
            cout<<a;
            int l=b.length();
            for(int i=max2;i<l;i++)
                printf("%c",b[i]);
            cout<<endl;
        }
        else
        {
            string x,y;
            x=a;
            for(int i=max1;i<l2;i++)
                x=x+b[i];
            y=b;
            for(int i=max1;i<l1;i++)
                y=y+a[i];
            if(x<y)
                cout<<x<<endl;
            else
                cout<<y<<endl;
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值