Camp Schedule CodeForces - 1138D (KMP按模式串构造)

一年一度紧张又刺激的暑假集训又要来啦!为此,老王开始制定实验室的暑假训练时间表。

经过苦思冥想,老王终于安排出了一个时间表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数组。

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89075549