Problem 71 : Ordered fractions
Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.
If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:
1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
It can be seen that 2/5 is the fraction immediately to the left of 3/7.
By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7.
1. 欧拉项目第71道题 : 有序的分数
考虑分数n/d,分子n 和 分母d 是正整数。 如果 n<d且n与d互质(n和d的最大公约数是1),分数n/d被叫做最简真分数。
如果我们按分数的大小的升序列出 d ≤ 8 的最简真分数的集合,则得到
1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
可以看出,2/5是紧靠3/7的左边的分数。
按大小的升序列出 d ≤ 1,000,000 的最简真分数,找出紧靠3/7的左边的分数的分子。
2. 求解分析
最简真分数n/d: 分子n小于分母d 且分子n和分母d互质。
这个集合有非常多的分数,紧靠3/7的左边的分数有什么特点呢?找出这个特点的话,这道题就能够解答。n/d = 3/7,n = 3d/7, 那么 n’ = (3d-1)/7, 如果n’/d被判断是最简真分数的话,n’/d 就是紧靠3/7的左边的分数,然后,我们从2到max_d枚举,找到分数值最大的那个分数n’/d,就是紧靠3/7的左边的分数。
3. C++ 代码实现
C++代码
#include <iostream>
#include <cassert>
using namespace std;
typedef struct _Fraction
{
int n; // numerator
int d; // denominator
double value; // n/d
} Fraction;
class PE0071
{
private:
int HCF(int m, int n) { return (n==0) ? m : HCF(n, m%n); }
// if n<d and HCF(n,d)=1, it is called a reduced proper fraction.
bool checkReducedProperFraction(int n, int d)
{
if (n < d && 1 == HCF(n, d))
{
return true;
}
return false;
}
public:
Fraction findReducedProperFractions(int max_d);
};
Fraction PE0071::findReducedProperFractions(int max_d)
{
Fraction fr;
Fraction fr_left;
fr_left.n = 1;
fr_left.d = max_d;
fr_left.value = (double)1.0/(double)max_d;
for(int d=3; d<=max_d; d++)
{
int n = (3*d-1)/7;
if (true == checkReducedProperFraction(n, d))
{
fr.n = n;
fr.d = d;
fr.value = (double)n/(double)d;
if (fr.value > fr_left.value)
{
fr_left = fr;
}
}
}
return fr_left;
}
int main()
{
PE0071 pe0071;
Fraction fr = pe0071.findReducedProperFractions(8);
assert(2 == fr.n && 5 == fr.d);
int max_d = 1000000;
fr = pe0071.findReducedProperFractions(max_d);
cout << "For d <= " << max_d << ", " << fr.n << "/" << fr.d;
cout << " is the fraction immediately to the left of 3/7." << endl;
return 0;
}
4. Python 代码实现
Python 代码
def HCF(a, b):
"""
Compute the greatest common divisor of a and b. Examples:
>>> HCF(14, 15) #co-prime
1
"""
while b != 0:
(a, b) = (b, a % b)
return a
def checkReducedProperFraction(n, d):
if n < d and 1 == HCF(n, d):
return True
return False
def findReducedProperFractions(max_d):
fr_left = (1, max_d, 1/max_d)
for d in range(3, max_d+1):
n = (3*d-1)/7
if True == checkReducedProperFraction(n, d):
fr = (n, d, n/d)
if fr[2] > fr_left[2]:
fr_left = fr
return fr_left
def main():
fr = findReducedProperFractions(8)
assert 2 == fr[0] and 5 == fr[1]
max_d = 10**6
fr = findReducedProperFractions(max_d)
print("For d <= %d, %d/%d" %(max_d, fr[0], fr[1]), end='')
print(" is the fraction immediately to the left of 3/7.")
if __name__ == '__main__':
main()