一年一度紧张又刺激的暑假集训又要来啦!为此,老王开始制定实验室的暑假训练时间表。
经过苦思冥想,老王终于安排出了一个时间表s。他把时间表表示为二进制字符串,训练为”1“,休息为”0“。
后来,老王翻知乎突然发现了一个”超有效哒时间表“t,知乎上说,这个时间表可以使同学收获最大。
老王决定修改自己的时间表,使暑假训练时间表中”超有效哒时间表“出现次数最多,并且休息和训练的天数不应该被改变,只改变它们的顺序。
请问你能帮老王重新安排一下时间表吗?
Input
第一行是老王的时间表s(1<=len(s)<=500000)。
第二行是”超有效哒时间表“t(1<=len(t)<=500000)。
每一个时间表只由”0“和”1“组成。
Output
只输出一行重新安排的时间表.
答案不唯一。
Examples
Input
101101
110
Output
110110
Input
10010110
100011
Output
01100011
Input
10
11100
Output
01
一看到这道题目,就直接傻眼了,这个怎么匹配出一个序列?以前都是在文本串中匹配模式串,这种题目我还是头一次见到,完全没有头绪。还是需要看大佬的题解
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<bits/stdc++.h>
const int maxn=500005;
typedef long long ll;
using namespace std;
const int inf=0x3f3f3f3f;
const double eps=1e-7;
int nex[maxn];
void next(string s)
{
int i=0;
int j=-1;
nex[0]=-1;
while(i<s.length())
{
if(j==-1||s[i]==s[j])
{
i++;
j++;
nex[i]=j;
}
else
j=nex[j];
}
}
int main()
{
string s,t;
cin>>s>>t;
next(t);
int one=0;
int zero=0;
for(int i=0;i<s.length();i++)
if(s[i]=='0')
zero++;
else
one++;
int cnt=0;
string ans;
while(zero&&one)
{
if(t[cnt]=='1')
{
if(one)
{
one--;
ans+='1';
}
else
break;
}
else
{
if(zero)
{
zero--;
ans+='0';
}
else
break;
}
cnt++;
if(cnt==t.length())
cnt=nex[cnt];
}
while(one--)
ans+='1';
while(zero--)
ans+='0';
cout<<ans<<endl;
return 0;
}
这道题目就是把目标字符串尽量多输出 出来,我们想一下。我们直接从文本串中找出1和0的数量,然后按照模式串的第几位是啥就输出啥,遍历到达模式串最后一个,然后我们再重新来一遍,但是这种做法是错误的,我举一个例子,就是10101000 和 101,这种情况,正确答案是 10101000 ,而我们上面那种想法是10110000,很显然,前面的是正确的,我们应该尽量多使用千前面已经出现的字符,我们就可以加以利用,构造出更多的模式串,我们就想到了next 数组来,这样就轻松解决了问题。好妙啊next数组。