ABC T3给我调蒙了(题解)

今日 ABC280,T3调了 40 分钟(还是太菜)

题目描述(翻译版):

问题描述

给定一个由0和1组成的长度为N的字符串S,以及一个整数K。字符串S中包含至少K个连续的1组成的子串(称为1-block)。任务是将从字符串S开始数第K个1-block移动到紧接在第K-1个1-block之后的位置,并输出移动后的字符串。

输入

  • 第一行包含两个整数N和K,分别表示字符串S的长度和要移动的1-block的序号。
  • 第二行是字符串S本身。

输出

  • 输出移动1-block后的字符串。

约束条件

  • 1 ≤ N ≤ 5 × 10^5
  • S是一个由0和1组成的长度为N的字符串。
  • 2 ≤ K
  • S中至少包含K个1-block。

示例输入与输出

示例输入 1

15 3
010011100011001

示例输出 1

010011111000001

解释:S中有四个1-block,分别是第2个字符、第5到7个字符、第11到12个字符和第15个字符。将第三个1-block(即第11到12个字符的"11")移动到第二个1-block(即第5到7个字符的"111")之后,得到输出字符串。

示例输入 2

10 2
1011111111

示例输出 2

1111111110

解释:S中有两个1-block,分别是第2到10个字符和第10个字符(这里第10个字符单独也算一个1-block,因为它后面跟着的是0)。将第二个1-block(即第10个字符的"1")移动到第一个1-block(即第2到10个字符的"111111111")之后(实际上是在其末尾,因为已经是最后一个字符了,但为了符合题目要求,我们将其视为“移动”到了紧接其后,即原位置),但由于移动后两个1-block合并,所以直接输出合并后的结果。

ok呀解题思路来临:

我想的是每次遇到 1 且前面是 0 这就是第不知道第几个的 1-block 的开头,而遇到 1 发现后面的数是 0 时这就是 1-block 的结尾。
而当他是第 k-1 个 1-block 就记录开头结尾位置,第 k 个同理。(我将它们以 bs,be,cs,ce 命名)

随后,在输出时我把他分为了四段,分别是:
第一段:bs以前与 第 k-1 个 1-block
第二段:ce 与 cs 的中间部分,将其移到前面输出
第三段:be 与 ce 的 0 部分,将其移到后面输出
第四段:ce 的后面
明显,第一段的部分其实是第一个字符到 be

这个思路其实是没有问题的,但下面的问题真的很难调:

    for(int i=0;i<=len;i++){
		if((a[i]=='1'&&a[i-1]=='0')){
			qs=i;
			//cout<<i<<" ";
		}
		if((a[i+1]=='0'&&a[i]=='1')){
			qe=i;
			ks++;
			
		}
		//cout<<ks<<" ";
		if(ks==k-1&&a[i+1]=='0'&&a[i]=='1'){
			bs=qs;
			be=qe;
		}
		if((ks==k&&a[i+1]=='0'&&a[i]=='1')){
			cs=qs;
			ce=qe;
			break;
		}
	}

这个代码是最开始的部分,但是这里有多处问题。

在第一个判断,若 i=0i-1 无值,所以当 1 出现在最开始时这个代码不显示(详见第二个样例)。
在第二个判断,同样的问题,$i=n-1$ 时会出现问题。
第四个判断与第二个判断的问题一样。

咋改?

第一个判断在后面增加:(a[i]=='1'&&i==0) 注意中间用 || 连接。
第二个判断在后面增加:(a[i]=='1'&&i==len-1) 注意中间用 || 连接。
第四个判断在后面增加:(ks==k&&a[i]=='1'&&i==len-1) 注意中间用 || 连接。
(ks 是目前有几个 1-block)

注意优先级!

这其实就没问题了,后面输出部分还需要费点脑筋纸上推一下。

ABC应该就不管AC code 了吧,放一下:

#include <bits/stdc++.h>
using namespace std;
char a[500005];
int main(){
	int n,k;
	cin>>n>>k;
	cin>>a;
	int len=strlen(a);
	int ks=0,bs,be,cs,ce;
	int qs,qe;
	for(int i=0;i<=len;i++){
		if((a[i]=='1'&&a[i-1]=='0')||(a[i]=='1'&&i==0)){
			qs=i;
			//cout<<i<<" ";
		}
		if((a[i+1]=='0'&&a[i]=='1')||(a[i]=='1'&&i==len-1)){
			qe=i;
			ks++;
			
		}
		//cout<<ks<<" ";
		if(ks==k-1&&a[i+1]=='0'&&a[i]=='1'){
			bs=qs;
			be=qe;
		}
		if((ks==k&&a[i+1]=='0'&&a[i]=='1')||(ks==k&&a[i]=='1'&&i==len-1)){
			cs=qs;
			ce=qe;
			break;
		}
	}
	//cout<<bs<<" "<<be<<" "<<cs<<" "<<ce;
	for(int i=0;i<=be;i++){
		cout<<a[i];
	}
	int p=ce-cs+1;
	for(int i=1;i<=p;i++){
		cout<<'1';
	}
	int q=cs-be-1;
	for(int i=1;i<=q;i++){
		cout<<'0';
	}
	for(int i=ce+1;i<len;i++){
		cout<<a[i];
	}
}