題目鏈接:請點擊
思路:
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;
}