B. Bit Flipping Codeforces Round #782 (Div. 2)

42 篇文章 0 订阅
7 篇文章 0 订阅
该博客探讨了一种二进制字符串翻转问题的解决方案,其中目标是在有限的翻转次数内使字符串变得尽可能大。文章通过分析翻转次数的奇偶性来决定如何选择和改变字符串中的0和1,以达到最优结果。具体策略包括在遇到0时消耗一次翻转次数以保持1为1,以及在所有其他位置最优转换后,根据剩余翻转次数处理最后一个字符。此外,文章还提供了C++代码实现来展示这一过程。
摘要由CSDN通过智能技术生成

You are given a binary string of length nn. You have exactly kk moves. In one move, you must select a single bit. The state of all bits except that bit will get flipped (00 becomes 11, 11 becomes 00). You need to output the lexicographically largest string that you can get after using all kk moves. Also, output the number of times you will select each bit. If there are multiple ways to do this, you may output any of them.

A binary string aa is lexicographically larger than a binary string bb of the same length, if and only if the following holds:

  • in the first position where aa and bb differ, the string aa contains a 11, and the string bb contains a 00.

Input

The first line contains a single integer tt (1≤t≤10001≤t≤1000) — the number of test cases.

Each test case has two lines. The first line has two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105; 0≤k≤1090≤k≤109).

The second line has a binary string of length nn, each character is either 00 or 11.

The sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, output two lines.

The first line should contain the lexicographically largest string you can obtain.

The second line should contain nn integers f1,f2,…,fnf1,f2,…,fn, where fifi is the number of times the ii-th bit is selected. The sum of all the integers must be equal to kk.

Example

input

Copy

6
6 3
100001
6 4
100011
6 0
000000
6 1
111001
6 11
101100
6 12
001110

output

Copy

111110
1 0 0 2 0 0 
111110
0 1 1 1 0 1 
000000
0 0 0 0 0 0 
100110
1 0 0 0 0 0 
111111
1 2 1 3 0 4 
111110
1 1 4 2 0 4

思路:可以发现如果k是偶数的话所有的数都不用变,1还是1,0还是0,所以我们遇到0的时候需要消耗一次不变次数,让他的操作数转化成单数,然后就可以把0变成1了,当前面的都最优转换的时候,如果k还有剩余,那么就放在最后一个字符上,然后再算一下操作步数,如果是奇数那么就变,如果是偶数那么就不变。因此我们列举的时候遍历的是0~n-2,s[n-1]单独去讨论。当操作数k是奇数的话,1变成0,0变成1,所以我们需要阻止1变成0,那么我们就在遇到1的时候消耗一个操作次数,让总共操作数变成偶数,这样就能保持1还是1,当我们用完消耗次数的时候,以后的1就都得转换成0了。

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long ll;
const int N=2e5+7;
ll n,k;
ll a[N];
void sove(){
	string s;
	cin>>n>>k;
	cin>>s;
	memset(a,0,sizeof a);
	ll con=k;
	if(k==0){
		cout<<s<<endl;
		for(int i=0;i<n;i++){
			cout<<a[i]<<" ";
		}
		cout<<endl;
		return ;
	}
	if(con%2!=0){
		for(int i=0;i<n-1;i++){
			if(s[i]=='0'){
				s[i]='1';
			}else{
				if(k>0){
					a[i]=1;
					k--;
				}else{
					s[i]='0';
				}
			}
		}
		if(k>0){
			a[n-1]=k;
			if((con-k)%2!=0){
				if(s[n-1]=='0')s[n-1]='1';
				else s[n-1]='0';
			}
		}else {
			if(s[n-1]=='0')s[n-1]='1';
			else s[n-1]='0';
		}
	}else{
		for(int i=0;i<n-1;i++){
			if(s[i]=='0'&&k>0){
				k--;
				s[i]='1';
				a[i]=1;
			}
		}
		if(k>0){
			a[n-1]=k;
			if((con-k)%2!=0){
				if(s[n-1]=='0')s[n-1]='1';
				else s[n-1]='0';
			}
		}
		
	}
	cout<<s<<endl;
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie() ,cout.tie() ;
	int t;
	cin>>t;
	while(t--){
		sove();
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于C语言的LDPC Modified Weighted Bit Flipping算法的代码示例: ```c #include<stdio.h> #include<stdlib.h> #include<math.h> #include<time.h> #define N 2048 //码长 #define K 1024 //信息位数 #define M 1024 //校验位数 #define p 0.01 //BSC信道误码率 #define MAX_ITER 50 //最大迭代次数 #define tau 2.0 //重要性参数 double H[M][N]; //LDPC矩阵 int d[N]; //接收端接收的码字 double r[N]; //接收端的对数似然比 double q[N]; //对数似然比的绝对值 double x[N]; //解码后的信息位 int perm[N]; //随机置换序列 double c[M]; //校验和 int iter_cnt = 0; //迭代次数计数器 //生成LDPC矩阵 void gen_LDPC_matrix() { int i,j,k; int col[N]; int row[M]; srand((unsigned)time(NULL)); for(i=0;i<M;i++) for(j=0;j<N;j++) H[i][j]=0; for(i=0;i<N;i++) perm[i]=i; for(i=0;i<M;i++) row[i]=i; for(i=0;i<N;i++) col[i]=i; for(i=0;i<N;i++) { k = rand()%(N-i) + i; j = perm[i]; perm[i] = perm[k]; perm[k] = j; } for(i=0;i<K;i++) { for(j=0;j<N/K;j++) { H[i][col[i*N/K+j]] = 1; } } for(i=K;i<M;i++) { for(j=0;j<N/K;j++) { H[i][col[(rand()%(N/K))+j*N/K]] = 1; } } } //BSC信道模拟 void BSC_channel() { int i; for(i=0;i<N;i++) { if((double)rand()/RAND_MAX < p) d[i] = 1-d[i]; r[i] = log((1-p)/p); if(d[i]==1) r[i] = -r[i]; q[i] = fabs(r[i]); } } //判断校验方程是否满足 int check_equations() { int i,j; int flag = 0; for(i=0;i<M;i++) { c[i] = 0; for(j=0;j<N;j++) { if(H[i][j]==1) c[i] += x[j]; } c[i] = fmod(c[i],2); if(c[i]!=0) flag = 1; } return flag; } //Modified Weighted Bit Flipping算法 void MWBF() { int i,j,k; double w[N]; double sum_w = 0; double f[N]; double delta[N]; double sum_delta = 0; double p0,p1; while(iter_cnt < MAX_ITER && check_equations()) { iter_cnt++; for(i=0;i<N;i++) { w[i] = 1/(1+exp(q[i])); if(x[i]==1) w[i] = 1-w[i]; sum_w += w[i]; } for(i=0;i<N;i++) { f[i] = 1; for(j=0;j<M;j++) { if(H[j][i]==1) f[i] *= (2*c[j]-1); } delta[i] = log((1-w[i])/w[i]) + f[i]/sum_w/tau; sum_delta += fabs(delta[i]); } while(sum_delta>1e-6) { k = 0; for(i=1;i<N;i++) { if(delta[i]>delta[k]) k = i; } x[k] = 1-x[k]; p0 = p/(1-p); p1 = (1-p)/p; for(i=0;i<M;i++) { if(H[i][k]==1) { if(c[i]==0) p1 *= (1-2*w[k]); else p0 *= (1-2*w[k]); } } r[k] = log(p0/p1); if(x[k]==1) r[k] = -r[k]; q[k] = fabs(r[k]); sum_delta = 0; for(i=0;i<N;i++) { f[i] = 1; for(j=0;j<M;j++) { if(H[j][i]==1) f[i] *= (2*c[j]-1); } delta[i] = log((1-w[i])/w[i]) + f[i]/sum_w/tau; sum_delta += fabs(delta[i]); } } sum_w = 0; sum_delta = 0; } } int main() { int i; double BER; gen_LDPC_matrix(); for(i=0;i<N;i++) d[i] = rand()%2; BSC_channel(); MWBF(); BER = 0; for(i=0;i<K;i++) BER += x[i] ^ d[i]; BER /= K; printf("BER = %f\n",BER); return 0; } ``` 该代码实现了一个N=2048,K=1024的LDPC码的解码,使用的是BSC信道。算法采用了Modified Weighted Bit Flipping算法,重要性参数tau默认为2。代码中使用了对数似然比,避免了浮点数下溢问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值