如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如,34 , 52 , 18 , 71 都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?
这道题的思路很简单,就是分子分母均从1-2000遍历,如果两数最大公约数等于1,则为既约分数。
为了提高代码运行速度,分子分母可利用一下嵌套循环进行遍历。
for (int denumerator = 2; denumerator <= 2020; denumerator++) {
for (int numerator = 1; numerator < denumerator; numerator++) {
……
}
}
两种做法,但是大同小异。
法一:
#include<iostream>
using namespace std;
//求x,y最大公约数
int greatest_common_divisor(int x, int y) {
int remainder = 1;//余数 被除数x 除数y
//大小定序 x > y
if (x < y) {
int temp = x;
x = y;
y = temp;
}
while (1) {
remainder = x % y;//求余数
if (remainder == 0) return y;//余数等于0 返回最大公约数y(除数)
x = y;
y = remainder;
}
}
int main()
{
int count = 0;
for (int denumerator = 2; denumerator <= 2020; denumerator++) {
for (int numerator = 1; numerator < denumerator; numerator++) {
if (greatest_common_divisor(denumerator, numerator) == 1) {
cout << "denumerator = " << denumerator << "\tnumerator = " << numerator << endl;
count++;
}
}
}
cout<<"既约分数对数:"<< count * 2 + 1;
return 0;
}
第一种方法是我自己写的,代码还是不够简洁规范。个人认为下面的更好点。
法二:
#include<iostream>
using namespace std;
int gcd(int a, int b) {
if (b==0)
return a;
return gcd(b, a%b);
}
int main() {
int num = 0;
const int N = 2020;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (gcd(i, j) == 1) {
num++;
// if (j == 2020)
// cout << i << '/' << j << '\n';
}
}
}
cout << num;
return 0;
}
其实不同的就是它在求最大公约数时用了递归算法,法一利用的时while循环。
最后还是介绍一下如何求得两数中最大公约数,他是用的欧几里和《几何原本》的求解方法。详情推荐阅读此文章
https://jingyan.baidu.com/article/c910274bb3cd56cd371d2d58.html