构造 - Binary String Reconstruction - CF 1400C

构造 - Binary String Reconstruction - CF 1400C

Consider the following process. You have a binary string (a string where each character is either 0 or 1) w of length n and an integer x. You build a new binary string s consisting of n characters. The i-th character of s is chosen as follows:

if the character w i − x w_{i−x} wix exists and is equal to 1, then si is 1 (formally, if i > x i>x i>x and w i − x = 1 w_{i−x}= 1 wix=1, then s i = 1 s_i= 1 si=1);
if the character w i + x w_{i+x} wi+x exists and is equal to 1, then si is 1 (formally, if i + x ≤ n i+x≤n i+xn and w i + x = 1 w_{i+x}= 1 wi+x=1, then s i = 1 s_i= 1 si=1);
if both of the aforementioned conditions are false, then si is 0.
You are given the integer x and the resulting string s. Reconstruct the original string w.

Input
The first line contains one integer t ( 1 ≤ t ≤ 1000 1≤t≤1000 1t1000) — the number of test cases.

Each test case consists of two lines. The first line contains the resulting string s ( 2 ≤ ∣ s ∣ ≤ 1 0 5 2≤|s|≤10^5 2s105, each character of s is either 0 or 1). The second line contains one integer x ( 1 ≤ x ≤ ∣ s ∣ − 1 1≤x≤|s|−1 1xs1).

The total length of all strings s in the input does not exceed 105.

Output
For each test case, print the answer on a separate line as follows:

if no string w can produce the string s at the end of the process, print −1;
otherwise, print the binary string w consisting of |s| characters. If there are multiple answers, print any of them.

Example
input

3
101110
2
01
1
110
1

output

111011
10
-1

分析:

  • 对于 s [ i ] = ′ 1 ′ s[i]='1' s[i]=1,可能有两种情况:
    • i > x i>x i>x && w [ i − x ] = ′ 1 ′ w[i-x]='1' w[ix]=1
    • i + x ≤ n i+x\le n i+xn && w [ i + x ] = ′ 1 ′ w[i+x]='1' w[i+x]=1
  • 对于 s [ i ] = ′ 0 ′ s[i]='0' s[i]=0,则: w [ i − x ] = ′ 0 ′ w[i-x]='0' w[ix]=0 && w [ i + x ] = ′ 0 ′ w[i+x]='0' w[i+x]=0

①、首先,我们可以根据 s [ i ] = ′ 0 ′ s[i]='0' s[i]=0 确定 w 中哪些位置一定要放 0,其他位置均放置 1 即可。

\qquad 因为,当我们处理完 s 中的 0后,对于剩下的 1 ,只要两侧存在一个 1 即可满足条件,
\qquad 我们为了方便起见,不考虑在哪一侧放 1,直接在非 0 的位置放 1

②、然后,我们考虑 s [ i ] = ′ 1 ′ s[i]='1' s[i]=1,来检测错误。此时,失败的条件就显然了,当我们放 1 的时候,如果对于某个 s [ i ] = ′ 1 ′ s[i]='1' s[i]=1,我们无法通过在左侧或右侧放置 1 时,我们就认为失败了。

在这里插入图片描述

③、最后,不要忘了把空着的字符都填充上 1,因为当步长较大时,会有区间更新不到。如上图,绿色的区域是我们会更新到的区域,中间的红色区域 [ n − x + 1 , 1 + x − 1 ] [n-x+1,1+x-1] [nx+1,1+x1] 是我们更新不到的区域。也就是当 n + 1 ≤ 2 x n+1\le 2x n+12x 时就会出现更新不到的区域。

注意: 多测清空答案数组时,要清空到字符串长度的后一位。

代码:

#include<cstdio>
#include<cstring>

using namespace std;

const int N = 100010;

int T, x;
char s[N], ans[N];

bool solve()
{
	int n = strlen(s + 1);
	for(int i = 0; i <= n + 1; i ++) ans[i] = '\0';
	
	for(int i = 1; i <= n; i ++)
		if(s[i] == '0')
		{
			if(i > x) ans[i - x] = '0';
			if(i + x <= n) ans[i + x] = '0';
		}
	for(int i = 1; i <= n; i ++)
		if(s[i] == '1')
		{
			bool flag = false;
			if(i > x && ans[i - x] != '0') 
			{
				ans[i - x] = '1';
				flag = true;
			}
			if(i + x <= n && ans[i + x] != '0') 
			{
				ans[i + x] = '1';
				flag = true;
			}
			if(!flag) return false;
		}
	for(int i = 1; i <= n; i ++) if(ans[i] == '\0') ans[i] = '1';

	return true;
}

int main()
{
	scanf("%d", &T);
	while(T --)
	{
		scanf("%s%d", s + 1, &x);		
		if(solve()) puts(ans + 1);
		else puts("-1");
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值