今日 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=0 则 i-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];
}
}