Educational Codeforces Round 17-C Two strings

C. Two strings
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

             You are given two strings a and b. You have to remove the minimum possible number of consecutive (standing one after another) characters from string b in such a way that it becomes a subsequence of string a. It can happen that you will not need to remove any characters at all, or maybe you will have to remove all of the characters from b and make it empty.

             Subsequence of string s is any such string that can be obtained by erasing zero or more characters (not necessarily consecutive) from string s.

Input

             The first line contains string a, and the second line — string b. Both of these strings are nonempty and consist of lowercase letters of English alphabet. The length of each string is no bigger than 105 characters.

Output

              On the first line output a subsequence of string a, obtained from b by erasing the minimum number of consecutive characters.

If the answer consists of zero characters, output «-» (a minus sign).

Examples
Input
hi
bob
Output
-
Input
abca
accepted
Output
ac
Input
abacaba
abcdcba
Output
abcba
Note

In the first example strings a and b don't share any symbols, so the longest string that you can get is empty.

In the second example ac is a subsequence of a, and at the same time you can obtain it by erasing consecutive symbols cepted from string b.


给两个字符串a与b,问删去字符串中连续的一部分字符后得到的新字符串是否是a的字串。prefix[i]的值代表b字符串以第0-i个字符作为子串时,第i个字符在a字符串的位置;suffix[i]的值代表b字符串以第i字符到末尾作为子串时,第i个字符在a字符串的位置。如果对于某一组i,j,prefix[i]<suffix[j],那么就代表着删去b字符串中i到j的部分后,剩下的字符串也为a字符串的子串。那么在处理好这两个数组后,枚举i,对于每一个i再二分查找满足prefix[i]<suffix[j]的j(这里没有试直接枚举行不行),更新能得到最长字串的值。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=1e5+500;
char str1[maxn],str2[maxn];
int prefix[maxn],suffix[maxn],len1,len2,ans,a,b;
void init()
{
    ans=-1;
    memset(prefix,-1,sizeof(prefix));
    memset(suffix,-1,sizeof(suffix));
    len1=strlen(str1);
    len2=strlen(str2);
    a=-1;
    b=len2;
    int index1=0,index2=len1-1,len3=0;
    for(int i=0; i<len2; i++)
    {
        while(index1<len1&&str1[index1]!=str2[i])index1++;
        if(index1>=len1)break;
        prefix[i]=index1;
        index1++;
        if(i+1>ans)
        {
            ans=i+1;
            a=i;
            b=len2;
        }
    }
    for(int i=len2-1; i>=0; i--)
    {
        while(index2>=0&&str1[index2]!=str2[i])index2--;
        if(index2<0)break;
        suffix[i]=index2;
        index2--;
        if(len2-i>ans)
        {
            ans=len2-i;
            a=-1;
            b=i;
        }
    }
}
void solve()
{
    for(int i=0; prefix[i]!=-1; i++)
    {
        int fr=i+1,ta=len2-1,mid;
        while(fr<=ta)
        {
            mid=(fr+ta)/2;
            if(fr==ta&&suffix[mid]>prefix[i])break;
            if(suffix[mid]<=prefix[i])fr=mid+1;
            if(suffix[mid]>prefix[i])ta=mid;
        }
        mid=max(fr,ta);
        if(ans<i+1+len2-mid)
        {
            ans=(i+1+len2-mid);
            a=i;
            b=mid;
        }
    }
    if(ans==-1)
    {
        cout<<"-"<<endl;
        return  ;
    }
    for(int i=0; i<=a; i++)cout<<str2[i];
    for(int i=b; i<len2; i++)cout<<str2[i];
    cout<<endl;
}
int main()
{
    while(~scanf("%s%s",&str1,&str2))
    {
        init();
        solve();
    }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值