【题解】P2118 比例简化

题面

题目传送门

前言

嗯?云落给出了两种做法,时间复杂度分别为 $ O(L^2) $ 与 $ O(L) $,都可以通过此题

正文

$ O(L^2) $ 做法

注意到 $ L \le 100 $,考虑暴力枚举分子分母,并与题干条件判断

小 trick:鉴于分数的浮点数计算可能会有精度误差,考虑交叉相乘转化为整数乘法比较

形式化地说,如:$ \frac{A}{B} \le \frac{i}{j} \Rightarrow A \times j \le B \times i $

$ O(L) $ 做法

很明显,$ i,j $ 对于 $ \frac{i}{j} $ 的贡献都是单调的,考虑双指针

详见代码块吧!

代码

$ O(L^2) $ 代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int a,b,L;
int main() {
	cin>>a>>b>>L;
	int ans1=L,ans2=1;
	for(int i=1;i<=L;i++){
		for(int j=1;j<=L;j++){
			if(__gcd(i,j)==1&&i*b>=j*a&&ans1*j>i*ans2){
				ans1=i;
				ans2=j;
			}
		}
	}
	cout<<ans1<<' '<<ans2<<endl;
	return 0;
}

$ O(L) $ 代码

#include<iostream>
using namespace std; 
int main(){
	int a,b,L;
	cin>>a>>b>>L;
	int i=1,j=1,ans1=L,ans2=1; 
	while(true){
		if(1ll*a*j<=1ll*b*i){
			if(1ll*i*ans2<1ll*j*ans1){
		        ans1=i;
		        ans2=j;
		    }
		    j++;
		    if(j>L){
		    	break;
			}
		}else{
			i++;
			if(i>L){
				break;
			}
		}
	}
	cout<<ans1<<' '<<ans2<<endl;
	return 0;
}

后记

两种做法都可以 AC,算法二需要有较强的思维能力

完结撒花

posted @ 2024-11-20 23:15  sunxuhetai  阅读(45)  评论(0)    收藏  举报