E - Checksum

E - Checksum

在这里插入图片描述


 ICPC训练赛的一道题,感觉还不错,难度不是很大。感觉考到了一个小小的思维。
题意:给出 n n n组数据,每组数据下包含两个整数 n , k n,k n,k,第二行输入一个长度为n的01串A,找到一个01串B长度为k,将A和B中1的个数相加得到D,将D转化成2进制,判断D与B是否一样,如果一样的话输出最小的B,否则输出None
 思路:B的长度为0到k,那么B中1的个数为0到k个,因为A中1的个数是已知的,所以我们D的大小是差不多已知的,我们循环0到k可以算出来D的大小,再每次将D的大小写成2进制。
 注意!这里有很重要一点,就是如何判断B中0和1的位置关系。只要我们这样写下去模拟几次就会发现,其实我们并不用关注B中的排列位置,当我们2进制下的D中1的个数和B中1的个数相同二者就是一样的,模拟几次就会发现这样的一个规律了。
 注意有一点!我们一定要将D转化的二进制个数和B的长度一样,不然就不用考虑了,如果不够长我们可以加0来写二进制,因为不影响大小。


#include <bits/stdc++.h>
#define int long long 
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define fi first
#define se second
#define PII pair<int,int>
using namespace std;
const int N = 1e5+5;
int a[N],b[N];
void solve ()
{
	string ans="99999999999999";//定义一个很大的string,用于判断
	int n,k;cin>>n>>k;
	string s;cin>>s;int cnt=0;
	for (int i=0;i<s.size();i++) 
	{
		if (s[i]=='1') cnt++;
	}
	for (int i=0;i<=k;i++)
	{
		string t;
		int now=cnt+i;
		int sss=0;
		while (now&&sss<k)//转化成二进制
		{
			t+=(now%2)+'0';
			sss++;
			now>>=1;
		}
		for (int i=t.size();i<k;i++)
		t+="0";//如果长度不够就补0
		reverse(t.begin(),t.end());//反转过来
		int pos=count(t.begin(),t.end(),'1');
		if (pos==i)
		{
			ans=min(ans,t);
		}
	}
	if (ans=="99999999999999") cout<<"None"<<'\n';
	else cout<<ans<<'\n';
}

signed main ()
{
	IOS;
	int T =1;
	cin>>T;
	while(T--) solve ();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值