【Codeforces】Codeforces Global Round 18

本文探讨了三个编程问题的解决方案。第一个问题是关于数组操作,通过检查元素总和是否可被数量整除来确定高度差。第二个问题涉及按位与操作,通过计算最优数字组合减少需要移除的数字。第三个问题研究如何通过翻转字符串中的'1'来转换字符串。每个问题都提供了详细的思路和代码实现。
摘要由CSDN通过智能技术生成

在这里插入图片描述
题意:可以通过选取下标不同的两个数,使其中一个数的值增加,另一个数的值减小。问:反复操作后高度差最小为?
思路:答案只可能为0或1。当所有数之和能被数字的个数整除时说明通过移动总是可以让高度差为0的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve()
{
	ll n,ans=0;
	cin>>n;
	for(int i=0;i<n;i++){
		ll t;
		cin>>t;
		ans+=t;
	} 
	if(ans%n)//不能整除
		cout<<1<<endl;
	else//可以整除
		cout<<0<<endl;
}

int main()
{
	ios::sync_with_stdio(false);
	int t=1;
	cin>>t;
	while(t--) solve();
	return 0;
}

在这里插入图片描述
题意:给定一个区间[l,r],为了使区间中所有的数字的按位与&结果不为零,你需要去掉其中一部分数字。问:最少去掉多少数字使按位与结果不为零。
思路:2e5大概是2的18次方,也就是18位,每一位上1最多的那一组数字是最优的,其余数字需要去掉,即结果为区间长度-最优数字个数。统计[1,2e5]区间所有数字每一位上的1个数的前缀和,方便查询。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
ll a[20][N];

void solve()
{
	ll l, r, ans = 0;
	cin>>l>>r; 
	ll len = r - l + 1;
	for(int i=0;i<20;i++){
		ans=max(a[i][r]-a[i][l-1],ans);//统计每一位上1的个数的最优值 
	}
	//区间长度-最优数字个数 
	cout<<len-ans<<endl;
} 

int main()
{
	int t;
	cin>>t;
	//每一位上1的个数的前缀和 
	for(int i=0;i<20;i++){
		for(int j=1;j<N;j++){
			a[i][j]=a[i][j-1]+((j>>i)&1);
		}
	}
	while(t--) solve();
	return 0;
}

在这里插入图片描述
题意:给定只包含’0’和’1’的两个串a和b,每次可以选中a串中的’1’并将a中的其它字符取反。问:至少需要多少次可以使a串变为b串?如果没有解输出-1.
大致思路:首先必须明晰:连续操作两次并选取不同下标的’1’相当于将不同位置的’0’和’1’互换。因此当a和b串中的’1’的个数相同时有解,或当选中a串中的一个’1’取反,此时,a串中的’1’的个数等于原来’0’的个数加1,也是有解的。否则无解。这样每两次操作可以还原两个值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
#define inf 0x3f3f3f3f

void solve()
{
	int cnt=0,n;
	string s,t;
	cin>>n;
	cin>>s>>t;
	int cnt1=count(s.begin(),s.end(),'1');
	int cnt2=count(t.begin(),t.end(),'1');
	for(int i=0;i<n;i++) {
		cnt+=(s[i]!=t[i]);
	}
	int res=inf;
	if(cnt1==cnt2)
		res=min(res,cnt);
	if(cnt2==n-cnt1+1)//b串中的'1'的个数等于a串中的'0'的个数加1 
		res = min(res,n-cnt);
	if(res==inf)
		cout<<-1<<endl;
	else
		cout<<res<<endl;
} 

int main()
{
	int t;
	cin>>t;
	while(t--) solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sophon、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值