Codeforces Round 725 (Div. 3)补题报告

比赛链接

一、概况

比赛名称:Codeforces Round 725 (Div. 3)
日期: 2024.2.3
晚上在家做了A和B,课上又做了C和F。
所以为什么F题这么简单?

二、正解

D. Another Problem About Dividing Numbers

1 题目描述

给定两个整数 a , b a, b a,b 和一个操作数 k k k。对于每一次操作,你有如下两种选择:

  • 选择一个能整除 a a a 的大于一的整数 c c c,用 a c \dfrac{a}{c} ca 替换 a a a
  • 选择一个能整除 b b b 的大于一的整数 c c c,用 b c \dfrac{b}{c} cb 替换 b b b

然后询问,是否存在一种操作方法,使得在恰好 k k k 次操作后, a = b a=b a=b

数据范围: 1 < a , b , k < 10 9 1 < a, b, k < {10}^9 1<a,b,k<109

2 大体思路

  1. 对于 k = 1 k=1 k=1 的情况:

    • 如果 a a a 能乘除 b b b ,且 a a a 不等于 b b b ,则可以通过一次操作使得它们相等。因此,输出YES
    • 否则,便无法仅通过一次操作使它们相等,输出NO
  2. 对于 k > 1 k>1 k>1 的情况:

    • 首先,通过质因数分解函数获取 a a a b b b 的质因数个数,分别记为 k a ka ka k b kb kb
    • 如果 k a + k b < k ka+kb<k ka+kb<k ,则表示质因数个数不足以进行 k k k 次操作,因为每次操作至少会使一个质因数被除去,输出NO
    • 如果 k a + k b ≥ k ka+kb \geq k ka+kbk ,则表示质因数个数足够进行 k k k 次操作,因为总共有 k a + k b ka+kb ka+kb 个质因数。输出YES

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
int fj(int x){//分解质因数
	int cnt=0;
	for(int i=2;i*i<=x;i++){
		while(x%i==0){
			x/=i;
			cnt++;
		}
	}
	if(x>1){
		cnt++;
	}
	return cnt;
}
int main(){
	ll t;
	cin>>t;
	while(t--){
		int a,b,k;
		cin>>a>>b>>k;
		ll ka=fj(a),kb=fj(b);
		if(k==1){
			if((a%b==0||b%a==0)&&a!=b){
				cout<<"YES";
			}
			else{
				cout<<"NO";
			}
		}
		else{
			if(ka+kb<k){
				cout<<"NO";
			}
			else{
				cout<<"YES";
			}
		}
		pr;
	}
	return 0;
}

G. Gift Set

1 题目描述

你有 x 个 x个 x红糖和 y y y个蓝糖,现在你需要用这些糖果做一些礼品盒,但规定每个礼品盒里必须有 a a a个红糖、 b b b个蓝糖或 b b b个红糖、 a a a个蓝糖。现在求他最多能做成多少个礼品盒。

2 大体思路

通过二分搜索寻找一个最大的礼品盒数量 m i d mid mid ,使得在该数量下,红糖和蓝糖的搭配满足题目要求。
首先处理特殊情况:如果 a a a 等于 b b b ,直接输出 m i n ( x / a , y / a ) min(x/a, y/a) min(x/a,y/a)
调整输入数据,确保 x < = y x <= y x<=y a < = b a <= b a<=b 。初始化二分搜索的上下界, l l l 为 0, r r r y y y 。通过二分搜索,每次取中间值 m i d mid mid ,调用函数确定是否能制作出 m i d mid mid 个礼品盒。函数中计算红糖和蓝糖的最大最小数量,确保能够满足糖果数量的要求。如果红糖最大数量不小于蓝糖最小数量,则当前 m i d mid mid 值有效,将 l l l 调整到 m i d mid mid 。否则,需要减小 m i d mid mid 的值,将 r r r 调整到 m i d − 1 mid - 1 mid1 。重复以上步骤,直到 l l l 大于 r r r ,输出最终结果 l l l

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll x,y,a,b;
int 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(r,mid);
	return l<=r;
}
void solve(){
	cin>>x>>y>>a>>b;
	if(a==b){
		cout<<min(x/a,y/a);
		return;
	}
	if(x>y){
		swap(x,y);
	}
	if(a>b){
		swap(a,b);
	}
	ll l=0,r=y;
	while(l<r){
		ll mid=(l+r+1)>>1;
		if(check(mid)){
			l=mid;
		}
		else{
			r=mid-1;
		}
	}
	cout<<l;
}
int main(){
	ll t;
	cin>>t;
	while(t--){
		solve();pr;
	}
	return 0;
}
  • 31
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值