一、题目
一个分数一般写成两个整数相除的形式:N/M,其中 M 不为0。最简分数是指分子和分母没有公约数的分数表示形式。
现给定两个不相等的正分数 N 1 / M 1 N1/M1 N1/M1 和 N 2 / M 2 N2/M2 N2/M2 ,要求你按从小到大的顺序列出它们之间分母为 K 的最简分数。
输入格式:
输入在一行中按 N/M 的格式给出两个正分数,随后是一个正整数分母 K,其间以空格分隔。题目保证给出的所有整数都不超过 1000。
输出格式:
在一行中按 N/M 的格式列出两个给定分数之间分母为 K 的所有最简分数,按从小到大的顺序,其间以 1 个空格分隔。行首尾不得有多余空格。题目保证至少有 1 个输出。
输入样例:
7/18 13/20 12
输出样例:
5/12 7/12
二、思路和注意事项
思路:
(1) 交叉相乘比较大小
若 a , b , c , d 均 为 正 数 , 若 a b > c d , 则 a d > b c 若a,b,c,d均为正数,若\frac ab> \frac cd,则ad>bc 若a,b,c,d均为正数,若ba>dc,则ad>bc
(2)将分数转化为小数后比较大小。
但是注意几种不同的数据类型的输出结果,如下:
(1) 5/(double)12 答案:0.416667
(2) 两个double型变量a,b.其中:a=5,b=12。 a/b 答案:0.416667
(3) double k = 5 / 12 k 答案:0
- 如果要化为最简正数,也就是找两个数的最大公约数。定义的方法为辗转相除法:
int gcd(int a, int b) //辗转相除法找到最大公约数
{
return b == 0 ? a : gcd(b, a % b);
}
说明:如果函数的返回值为1,则说明两个数的最大公约数为1,即为最简分数。如果是最简分数就输出。
- 定义行首尾不能有多余的空格方法:定义flag,初始值为false.
当遇到第一个最简分数时,flag仍然为false,输出格式为 printf("%d/%d", i, k);
再让lfag变为true;输出格式为: printf(" %d/%d", i, k);
因此第一个最简分数以后,最后一个之前的最简分数之间都间隔1个空格
三、AC代码
#include <iostream>
#include<algorithm>
using namespace std;
int gcd(int a, int b) //辗转相除法找到最大公约数
{
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
int n1, m1, n2, m2, k;
bool flag = false;
scanf("%d/%d %d/%d %d", &n1,&m1,&n2,&m2,&k);
if (m1 * n2 < n1 * m2)
//输入的时候题目没有说明第一个输入的分数必然大于第二个,通过交叉相乘比较两个分数的大小。
{
swap(n1, n2);
swap(m1, m2);
} //该交换保证了第一个分数一定小于第二个数
for (int i = 1; i < k; i++)
{
if ((n1 * k < i * m1) && (i * m2 < k * n2))
{
if (gcd(i,k) == 1) //表示二者没有最大公约数,也就是最简分数。
{
if (flag == false)
{
printf("%d/%d", i, k);
}
else
{
printf(" %d/%d", i, k);
}
flag = true;
}
}
}
}
结果: