题目链接:请点击
思路:
step1:首先找到3个数(两个分数的分母M1,M2和给定的K)的最小公倍数。
step2:定义int型数组,用于存储K的所有因子(数组下标对应数字,若该数字是K的因子,则置其为1)。
step3:将两个分数的分子通分得到n1与n2,for循环遍历n1与n2之间的数字i,若该数恰好可以被化简(i%(lcm/K)==0)说明i与K可以组成一个分数(因为此时i是在最小公倍数中循环的,而最后输出的分母是最简K,只有当i也能够被化简时才可以与K组成一个分数)。
step4:若循环数i可以被化简,随后判断K的所有因子是否也是i的因子,若是则说明i/K是可化简的;反之i/K是最简分数。
注1:题给出的“之间”很模糊,心理就犯嘀咕(是否包括边界)。测试点2未过(循环的时候包括了n1与n2),然后,改代码不包括边界就过了。
AC代码:
#include<iostream>
using namespace std;
int GCD(int n1,int n2){//最大公约数
while(n1!=n2){
if(n1>n2) n1=n1-n2;
else n2=n2-n1;
}
return n1;
}
int LCM(int n1,int n2){//最小公倍数
int gcd=GCD(n1,n2);
int lcm=n1*n2/gcd;
return lcm;
}
int main(){
int n1,n2,m1,m2,K;
scanf("%d/%d %d/%d %d",&n1,&m1,&n2,&m2,&K);
int lcm1=LCM(m1,m2);//找到2个分母的最小公倍数
int lcm2=LCM(m1,K);
int lcm=LCM(lcm1,lcm2);//3个数的最小公倍数
n1=n1*(lcm/m1); n2=n2*(lcm/m2);//通分
int factor[lcm+1]={0};//存储lcm的因数 下标对应因数
for(int i=2;i*i<=K;i++){
if(K%i==0) {//i是lcm的因数 将其因子置1
factor[i]=1;
factor[K/i]=1;
}
}
int flag=0;//用于控制显示空格
if(n1>n2){int t=n2; n2=n1; n1=t;}//始终让n1<n2
for(int i=n1+1;i<n2;i++){//见注1
if(i%(lcm/K)==0) {
int num=i/(lcm/K);//将分子化简
int cnt=0;//用于判断分子分母是否有公因子
for(int j=2;j*j<lcm;j++){
if(factor[j]==1&&num%j==0){//说明有公因子
cnt=1;
break;
}
}
if(cnt==0){//若无公因子
if(flag) cout<<" ";
cout<<num<<"/"<<K;
flag=1;
}
}
}
return 0;
}