Codeforces Round 859 (Div. 4) A~G

文章包含了多个编程问题的解决思路,如PlusorMinus、GrabtheCandies等,涉及数组操作、字符串处理、奇偶数判断、前缀和的应用以及二分查找等算法。每个问题的解决方法都提供了简洁的代码实现。
摘要由CSDN通过智能技术生成

目录

A. Plus or Minus

 B. Grab the Candies

 C. Find and Replace

 D. Odd Queries

 E. Interview

F. Bouncy Ball 

 G. Subsequence Addition


A. Plus or Minus

思路:按题目要求输出即可。 

void solve() {
	int a,b,c;
	cin>>a>>b>>c;
	if(a-b==c)cout<<"-"<<endl;
	else cout<<"+"<<endl;
}

 B. Grab the Candies

思路:把偶数全放前面,把奇数全放后面,这样只用看偶数之和是否严格大于奇数之和。

void solve() {
	int n;
	cin>>n;
	int sum1=0,sum2=0;
	FOR(1,n) {
		int x;
		cin>>x;
		if(x&1)sum1+=x;
		else sum2+=x;
	}
	if(sum2>sum1)yes;
	else no;
}

 C. Find and Replace

思路:先模拟赋值,最后看字符串是否01相间

void solve() {
	map<char,int>mp;
	int n;
	cin>>n;
	string s;
	cin>>s;
	FOR(0,n-1) {
		if(mp[s[i]]) {
			if(mp[s[i]]==-1)s[i]='0';
			else s[i]='1';
			continue;
		}
		if(i&1)mp[s[i]]=1,s[i]='1';
		else mp[s[i]]=-1,s[i]='0';
	}
	FOR(0,n-2) {
		if(s[i]==s[i+1]) {
			no;
			return;
		}
	}
	yes;
}

 D. Odd Queries

思路:若要数组总和为奇数,则数组内有奇数个奇数。利用前缀和快速判断改变完之后数组内奇数的个数即可。

void solve() {
	int n,q;
	cin>>n>>q;
	FOR(1,n)cin>>a[i],sum[i]=sum[i-1]+a[i]%2;
	while(q--) {
		int l,r,k;
		int s=0;
		cin>>l>>r>>k;
		s+=sum[l-1]+sum[n]-sum[r];
		s+=(k%2)*(r-l+1);
		if(s%2)yes;
		else no;
	}
}

 E. Interview

思路:利用前缀和二分判断区间内的总和是否合法,若左区间合法则r=mid,反之l=mid+1,直至l=r。

void solve() {
	int n,x;
	cin>>n;
	FOR(1,n) {
		cin>>x;
		sum[i]=sum[i-1]+x;
	}
	int l=1,r=n;
	while(l!=r) {
		int mid=(l+r)/2;
		cout<<"? "<<mid-l+1<<" ";
		FOR(l,mid)cout<<i<<" ";
		cout<<endl;
		cin>>x;
		if(sum[mid]-sum[l-1]!=x)r=mid;
		else l=mid+1;
	}
	cout<<"! "<<l<<endl;
}

F. Bouncy Ball 

思路:按照题意模拟即可,主要就是判断有没有重复一开始的两步行为,若有则输出-1。

void solve() {
	map<string,PII>mp;
	mp["DL"]= {1,-1},mp["DR"]= {1,1},mp["UR"]= {-1,1},mp["UL"]= {-1,-1};
	int n,m,x1,y1,x2,y2,st=0,st2=0;
	string s;
	cin>>n>>m>>x1>>y1>>x2>>y2>>s;
	int xp=x1,yp=y1,xp2,yp2;//xp,yp记录第一步动作
	auto now=mp[s];
	if(x1+now.first<1||x1+now.first>n)xp2=x1-now.first;//xp2,yp2记录第二步动作
	else xp2=x1+now.first;
	if(y1+now.second<1||y1+now.second>m)yp2=y1-now.second;
	else yp2=y1+now.second;
	while(1) {
		if(x1==x2&&y1==y2) {
			cout<<st<<endl;
			return;
		}
		int x=x1+now.first,y=y1+now.second;
		int f=0;
		if(x<1||x>n)now.first=-now.first,st++,f=1;
		if(y<1||y>m)now.second=-now.second,st++,st-=f;//减去f是为了特判撞到墙角的情况,若不判会使st+2
		x1=x1+now.first,y1=y1+now.second;
		if(x1==xp&&y1==yp) { //若第一步重合了则进一步判断下一步是否重合
			int kx,ky;
			if(x1+now.first<1||x1+now.first>n)kx=x1-now.first;
			else kx=x1+now.first;
			if(y1+now.second<1||y1+now.second>m)ky=y1-now.second;
			else ky=y1+now.second;
			if(kx==xp2&&ky==yp2) {
				cout<<-1<<endl;
				return;
			}
		}
	}
}

 G. Subsequence Addition

 思路:我们考虑最“坏”的情况,数组为1,1,2,4,8,16......,可以发现它们都是2的幂次,通过二进制的思想可以发现他组成数的范围为1~sum,所以1~sum都能利用前面的数组成,利用前缀和判断下一个数是否大于sum即可。

void solve() {
	int n;
	cin>>n;
	FOR(1,n)cin>>a[i];
	sort(a+1,a+n+1);
	FOR(1,n) sum[i]=sum[i-1]+a[i];	
	if(a[1]!=1) {
		no;
		return;
	}
	FOR(2,n) {
		if(a[i]>sum[i-1]) {
			no;
			return;
		}
	}
	yes;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值