题目
问题描述
给定一个由01所组成的字符串,总共要对其进行 K K K次操作,每次操作是从中选择一位,将除此位以外的其余位均进行翻转,问经过 k k k次操作可以得到的最大字典序的序列。
分析
1.对于一个从未选择过的位置,将进行
k
k
k次翻转,而每选择一个位置,就可以使其的翻转次数减一。
2.对于每个位置,只有进行奇数次翻转才有意义,偶数次翻转对结果无影响。
所以我们从高往低进行枚举,考虑这个位置本应该进行翻转的次数,以及是否需要进行调整(调整也就是对其分配一次操作);如果最后仍然有多余的操作,偶数次则随便置于一处即可,奇数次则分配给最低位的1,并将其置为 0 0 0。
代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define fir(i, a, b) for (ll i = (a); i <= (b); i++)
#define rif(i, a, b) for (ll i = (a); i >= (b); i--)
const int N=2e5+5;
char a[N];
ll t,n,k,tmp,b[N];
int main(){
cin>>t;
while(t--){
memset(b,0,sizeof b);
cin>>n>>k;
tmp=k;
getchar();
fir(i,1,n){
cin>>a[i];
}
ll flag=k%2;
fir(i,1,n){
if(!tmp){
if(flag){
if(a[i]=='1')a[i]='0';
else if(a[i]=='0')a[i]='1';
}
}
else if(a[i]=='1'){
if(flag){
tmp--;
b[i]++;
}
}
else if(a[i]=='0'){
if(!flag){
tmp--;
b[i]++;
}
a[i]='1';
}
}
if(tmp){
if(tmp%2){
b[n]+=tmp;
a[n]='0';
}
else{
b[1]+=tmp;
}
}
fir(i,1,n)cout<<(char)a[i];
cout<<endl;
fir(i,1,n){
cout<<b[i]<<" ";
}
cout<<endl;
}
return 0;
}
/*
6
6 3
100001
6 4
100011
6 0
000000
6 1
111001
6 11
101100
6 12
001110
*/
*/