1062 最简分数 (20 分)
一个分数一般写成两个整数相除的形式:N/M,其中 M 不为0。最简分数是指分子和分母没有公约数的分数表示形式。
现给定两个不相等的正分数 N1 /M1和 N2 /M2 ,要求你按从小到大的顺序列出它们之间分母为 K 的最简分数。
输入格式:
输入在一行中按 N/M 的格式给出两个正分数,随后是一个正整数分母 K,其间以空格分隔。题目保证给出的所有整数都不超过 1000。
输出格式:
在一行中按 N/M 的格式列出两个给定分数之间分母为 K 的所有最简分数,按从小到大的顺序,其间以 1 个空格分隔。行首尾不得有多余空格。题目保证至少有 1 个输出。
输入样例:
7/18 13/20 12
输出样例:
5/12 7/12
测试点分析:
测试点2和测试点4应该是分母与与K值数值太大,因数很多,很多可以约分的没有判断出来可以约分就错了,比如公因数可能是大的素数。
思路:
先用数组a统计2000以内的素数。
把所有分子(n1,n2,i)通分(M1、M2、K三个分母),通过比较分子大小if ( i>n1 && i<n2 )
来判断是否在合法区间内,就不用担心用分数大小比较产生的double精度问题。
再看分子与K是否有公因数if( 分子 % 素数[数组] !=0 && K % 素数[数组 != 0 )
(才开始想当然认为所有数因子无非2 3 5 7,后来才想起有素数这玩意T T),没有则赋值未通分前的分子给结构数组(不用结构数组也可以,毕竟只需要一个数组来存分子,不过我懒得改了= =)
最后输出分子数组就好
结果:
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
struct fenshu{
int zi;
}fs[99999];
int ip(int x);
ip(int x)
{
if(x==2)return 1;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)return 0;
}
return 1;
}
int main(){
int a[9999];
int kk=0,kkk=0;
for(int i=2;i<2000;i++){
if(ip(i)==1)a[kkk++]=i;
}
double n1,n2,m1,m2;
int k;
kk=0;
int i;
double nn1,nn2,nn;
scanf("%lf/%lf %lf/%lf %d",&n1,&m1,&n2,&m2,&k);
double f1=n1/m1,f2=n2/m2;
double tmp;
if(f1>f2){tmp=n1;n1=n2;n2=tmp;tmp=m1;m1=m2;m2=tmp;}
nn1=n1*m2*k;nn2=n2*m1*k;
for(i=1;i<=k;i++)
{
nn=i*m1*m2;
if(nn>nn1&&nn<nn2)
{
int flg=0;
for(int ki=0;ki<kkk;ki++)
{
if( (i%a[ki] )==0&& (k%a[ki] ) ==0)flg=1;
}
if(flg==0)fs[kk++].zi=i;
}
}
for(i=0;i<kk;i++)
{
printf("%d/%d",fs[i].zi,k);
if(i!=kk-1)printf(" ");
}
return 0;
}