线上OJ:

一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid=1966

核心思想:

1、本题的约束条件有四个

1.1 A′ 和 B′ 均不大于 L
1.2 A′ 和 B′ 互质
1.3 A′B′ ≥ AB
1.4 A′B′ − AB 的值尽可能小

2、仔细观察数据范围,发现A 和 B的范围很大,但是 L 的范围非常小,只有1-100。所以只需 将 A' 和B' 直接在 L 内枚举 即可
3、有两个常用公式要记住:

int gcd(int a, int b) {return b ? gcd(b, a%b): a;} // 最大公约数
int lcm(int a, int b) {return a / gcd(a, b) * b;} // 最小公倍数

4、int / int 依然为 int 。 如需使 其结果为 double, 需先*1.0(如 ab1 = a * 1.0/ b),这样编译器会自动将式子按照double来计算。 或者都先强制转换为double,如:ab1 = (double)a / (double)b

题解代码:

#include <bits/stdc++.h>
using namespace std;

int gcd(int a, int b) {return b ? gcd(b, a%b): a;}
int lcm(int a, int b) {return a / gcd(a, b) * b;}

int a, b, l, ans1, ans2;
double ab1, ab2, mi = 1000000.0;

int main()
{
    scanf("%d%d%d", &a, &b, &l);
    ab1 = a * 1.0/ b;
    
    for(int i = 1; i <= l; i++)
        for(int j = 1; j <= l; j++)
        {
            if(gcd(i,j) == 1)
            {
                ab2 = i * 1.0 / j;
                if( (ab2 >= ab1) && ((ab2 - ab1) < mi ) )
                {
                    mi = ab2 - ab1;
                    ans1 = i;
                    ans2 = j;
                }
            }
        }

    cout << ans1 << ' ' << ans2 << endl;
    return 0;
}