【题目链接】
ybt 1966:【14NOIP普及组】比例简化
洛谷 P2118 [NOIP2014 普及组] 比例简化
【题目考点】
1. 枚举
【解题思路】
观察L的范围,为1~100,因此可以分别枚举A’与B’的值,判断哪一组A’/B’ ≥ A/B,并找出A’/B’- A/B最小的那一组值。
对于A’与B’是否互质,可以预先判断二者的最大公约数是否为1。
这一步不做其实也可以。由于A’与B’都是从小到大遍历的,对于A’/B’比值相同的情况,一定是先遍历到A’与B’互质的情况,后遍历到二者不互质的情况。在求最小值时只需要使用’<',即可取到前面的情况而不取后面的情况。
【题解代码】
解法1:使用最大公约数函数判断二者是否互质
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int gcd(int a, int b)
{
if(b == 0)
return a;
return gcd(b, a%b);
}
int main()
{
int a, b, l, ri, rj;//ri,rj记录结果
double d, d1, mind = INF;//mind:最小差值
cin >> a >> b >> l;
d = (double)a/b;//A/B
for(int i = 1; i <= l; ++i)
for(int j = 1; j <= l; ++j)
{
//i:A' j:B'
if(gcd(i, j) == 1)//最大公约数为1,二者互质
{
d1 = (double)i/j;
if(d1 >= d && d1-d < mind)
{
mind = d1-d;
ri = i;
rj = j;
}
}
}
cout << ri << ' ' << rj;
return 0;
}
解法2:不判断互质
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int main()
{
int a, b, l, ri, rj;//ri,rj记录结果
double d, d1, mind = INF;//mind:最小差值
cin >> a >> b >> l;
d = (double)a/b;//A/B
for(int i = 1; i <= l; ++i)
for(int j = 1; j <= l; ++j)
{
//i:A' j:B'
d1 = (double)i/j;
if(d1 >= d && d1-d < mind)
{
mind = d1-d;
ri = i;
rj = j;
}
}
cout << ri << ' ' << rj;
return 0;
}