思路:贪心的思想,高位的0肯定优先置1。此时分两种情况:
1、如果k<连续0的段数
只需要从高位往低位把连续的 k段连的0区间变为1即可。
2、如果k>连续0的段数
输出的答案全为1
原因:若把连续的0区间都变为1后(即字符串全为1),k还剩偶数次,显然字符串不变,答案全为1;若还剩下奇数次,可以在上一次置1时,把0区间相邻的1置0,然后再把新的0区间置1,此时k还剩下偶数次,与第一种情况相同。
例如: 错误情况: 正确情况:
10111 k = 4 10111 k = 4
11111 k = 3 10011 k = 3
11111 k = 2
两个特判:
1、n=1
2、k=1 且 s = 111.11,此时结果为111.10
代码如下:
#include<iostream>
#include<string>//这里不加会CE
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while(T--)
{
int n;
ll k;
cin >> n >> k;
string a;
cin >> a;
if (n == 1) //特判
{
if (k % 2) cout << "0" << endl;
else cout << "1" << endl;
continue;
}
if (k == 1) // 特判
{
bool flag = false;
for (int i = 0; i < n; i++)
{
if (a[i] != '1')
{
flag = true;
break;
}
}
if (!flag)
{
for (int i = 0; i < n - 1; i++) cout << "1";
cout << "0" << endl;
continue;
}
}
for (int i = 0; i < n; i++)
{
int j = i;
while(a[j] == a[j+1] && j + 1 < n) j++;
if (a[i] == '0' && k > 0)
{
for (int l = i; l <= j; l++) a[l] = '1';
k--;
}
i = j;
}
cout << a << endl;
}
return 0;
}