CF1538 补题报告

CF1538补题报告(A.B.C.D.F.G.)
Codeforces Round 725 (Div. 3)

A. Stone Game

A. 石头游戏

题意

给定一个序列,每次只能删除最左边或最右边的元素,求出删除最大和最小值需要多少次删除操作。

思路

找到最大值和最小值所在的位置,取四种情况中的最小值。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a[105],t,maxn=1,minna=1;
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			
		}
		maxn=1,minna=1;
		for(int i=2;i<=n;i++){
			if(a[i]>a[maxn]){
				maxn=i;
			}
			if(a[i]<a[minna]){
				minna=i;
			}
		}
		cout<<min((maxn+n-minna+1),min((minna+n-maxn+1),min(max(maxn,minna),max(n-maxn+1,n-minna+1))))<<endl;
	}
	return 0;
}

B. Friends and Candies

B. 朋友与糖果

题意

给定一个序列代表每人的糖果数量,每次操作可以将一个人的部分糖果分给另一个人,求使每个人所有的糖果均等需进行多少次操作

思路

求出平均值,并判断是否为整数,非整数直接输出-1,因为分配糖果都是从糖果多的人分给糖果少的人,所以统计有多少人的糖果大于平均值

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int t,n,a[200005],b,sum;
bool fl;
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		b=0,fl=0,sum=0;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			b+=a[i];
			if(i>1&&a[i]!=a[i-1]){
				fl=1;
			}
		}
		if(b%n!=0){
			printf("-1\n");
			continue;
		}
		if(!fl){
			printf("0\n");
			continue;
		}
		b/=n;
		for(int i=1;i<=n;i++){
			if(b<a[i]){
				sum++;
			}
		}
		printf("%d\n",sum);
	} 
	return 0;
}

C. Number of Pairs

C. 对数

题意

给定一个序列和l,r,求在序列中有多少对数的和在[l,r]这个区间内

思路

首先将此序列排序,然后遍历数对的第一个数,二分查找第二个数的区间,输出所有区间的和

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long t,n,a[200005],b,sum,l,r,la,ra;
bool fl;
int main(){
	cin>>t;
	while(t--){
		cin>>n>>l>>r;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		sum=0;
		for(int i=1;i<=n;i++){
			sum+=upper_bound(a+1+i,a+n+1,r-a[i])-lower_bound(a+1+i,a+n+1,l-a[i]);
		}
		
		printf("%lld\n",sum);
	} 
	return 0;
} 

D. Another Problem About Dividing Numbers

D. 关于除法的另一个问题

题意

给定两个整数以及操作数k,每次操作可以使a或b除以一个数,问是否可以在除以一个数k次操作后使得a=b

思路

质因数之和即操作的最大值,所以此题只需求二数的质因数个数之和是否大于k即可,但是如果a、b不成倍数关系且k=1,输出NO

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long ans,t,a,b,k;
int fenjie(int a){
	int sum=0;
	for(int i=2;i*i<=a;i++){
		while(a%i==0){
			a/=i;
			sum++;
		}
	}
	if(a>1){
		sum++;
	}
	return sum;
}
int main(){
	cin>>t;
	while(t--){
		cin>>a>>b>>k;
		int ka=fenjie(a),kb=fenjie(b);
		if(k==1){
			if((a%b==0||b%a==0)&&a!=b){
				printf("YES\n");
			}
			else{
				printf("NO\n");
			}
		}
		else{
			if(ka+kb>=k){
				printf("YES\n");
			}
			else{
				printf("NO\n");
			}
		}
		
	}
	return 0;
}

F. Interesting Function

F. 有趣的函数

题意

给定两个正整数,使第一个数不断加一,一直加到第二个数,求出此过程中变化的位数的总数

思路

l,r每次去掉个位,遍历所有位,求r-l的总和

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long ans,t,a,b;
int main(){
	cin>>t;
	while(t--){
		cin>>b>>a;
		ans=0;
		while(a!=0){
			ans+=a-b;
			a/=10,b/=10;
		}
		printf("%lld\n",ans);
	} 
	return 0;
}

G. Gift Set

G. 礼品套装

题意

给定有x个红糖,y个蓝糖,由它们组成多个礼品盒,要求每个礼品盒内必须要有a个红糖b个蓝糖或者是a个蓝糖b个红糖,问最多能组成多少个礼品盒

思路

利用二分查找, m i d mid mid 为礼品盒数,其中要保证红糖数量的最大值不小于蓝糖数量的最小值

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long t,x,y,a,b;
bool check(int mid){
	int l=ceil(1.0*(x-b*mid)/(a-b));
	int r=floor(1.0*(y-a*mid)/(b-a));
	l=max(l,0);
	r=min(mid,r);
	return l<=r;
}
int main(){
	cin>>t;
	while(t--){
		cin>>x>>y>>a>>b;
		if(a==b){
			printf("%lld\n",min(x/a,y/a));
			continue;
		}
		if(x>y){
			swap(x,y);
		}
		if(a>b){
			swap(a,b);
		}
		int l=0,r=y;
		while(l<r){
			int mid=(l+r+1)/2;
			if(check(mid)){
				l=mid;
			}
			else{
				r=mid-1;
			}
		}
		printf("%lld\n",l);
	}
	return 0;
}
相关推荐
蜀黍@猿33 分钟前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧40935 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
zh路西法1 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
蜀黍@猿2 小时前
C/C++基础错题归纳
c++
雨中rain2 小时前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
oneouto2 小时前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh322 小时前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
ALISHENGYA3 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战项目二)
数据结构·c++·算法