【题解】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,算法二需要有较强的思维能力
完结撒花

浙公网安备 33010602011771号