【题目链接】
【题目考点】
1. 枚举
【解题思路】
设这个分数的分母为m,分子为c
- 枚举对象:分母m,分子c
- 枚举范围: 1 ≤ m ≤ N 1\le m \le N 1≤m≤N, 1 ≤ c < m 1\le c < m 1≤c<m
- 判断条件: c m < a b \frac{c}{m} < \frac{a}{b} mc<ba
求满足条件的情况中 c m \frac{c}{m} mc最大时的c与m。
只要让 m m m与 c c c都从小到大循环。
假设当前记录的满足条件的 c c c与 m m m分别为 c 1 c_1 c1与 m 1 m_1 m1, c 1 m 1 \frac{c_1}{m_1} m1c1是最简分数。
如果后面发现当c变为 c 2 c_2 c2,m变为 m 2 m_2 m2时,满足 c 1 m 1 = c 2 m 2 \frac{c_1}{m_1}=\frac{c_2}{m_2} m1c1=m2c2,而且有 c 1 ≤ c 2 c_1\le c_2 c1≤c2且 m 1 ≤ m 2 m_1 \le m_2 m1≤m2,这时不取 c 2 c_2 c2与 m 2 m_2 m2,保留 c 1 c_1 c1与 m 1 m_1 m1。
这样可以保证最后得到的 c c c与 m m m构成的分数是最简分数。
外层由m从1循环到n,内层由c从1循环到m-1。
只要当前 c m ≥ a b \frac{c}{m}\ge \frac{a}{b} mc≥ba,那么直接跳出c的循环。因为如果继续c的循环,c只会越来越大, c m \frac{c}{m} mc会越来越大,后面得到的都是不满足条件的情况。
【题解代码】
解法1:枚举
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, a, b, m_mx, c_mx;//m_mx, c_mx:结果的分母与分子
cin >> n >> a >> b;
double mx = 0, a_b = (double)a/b, c_m;//mx:小于a/b的最大的c/m的值
for(int m = 1; m <= n; ++m)//m:分母
for(int c = 1; c < m; ++c)//c:分子
{
c_m = (double)c/m;
if(c_m < a_b)//满足c/m < a/b
{
if(c_m > mx)//如果c/m大于mx,那么更新mx
{
mx = c_m;
c_mx = c;
m_mx = m;
}
}
else//如果c/m >= a/b,那么后面c/m会越来越大,没有必要循环了
break;
}
cout << c_mx << ' ' << m_mx;
return 0;
}