OpenJudge NOI 2.1 7832:最接近的分数

【题目链接】

OpenJudge NOI 2.1 7832:最接近的分数

【题目考点】

1. 枚举

【解题思路】

设这个分数的分母为m,分子为c

  • 枚举对象:分母m,分子c
  • 枚举范围: 1 ≤ m ≤ N 1\le m \le N 1mN 1 ≤ c < m 1\le c < m 1c<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 c1c2 m 1 ≤ m 2 m_1 \le m_2 m1m2,这时不取 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} mcba,那么直接跳出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;
}

猜你喜欢

转载自blog.csdn.net/lq1990717/article/details/128571922