PAT 1062 最簡分數

題目鏈接:請點擊
思路:
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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章