P1029 最大公約數和最小公倍數問題
首先你要知道一點:
若A×B代表二者的乘積,也就是二者最大的乘積,
如果用A×B除以二者的最小公倍數,就能得到了二者的最大公約數
當然前提是這兩個數要是非零的兩個整數
最大公約數=A×B/最小公倍數
反過來,最小公倍數=A×B/最大公約數
那么這道題就很簡單地做出來了:
方法一:枚舉
①

#include<iostream> #include<cmath> using namespace std; int gcd(int a,int b)//求最大公約數 { while(b!=0)//輾轉相除法求最大公約數 { int qwq=a%b; a=b; b=qwq; } return a; //return b == 0 ? a : gcd(b,a%b); } int main() { int x,y; cin>>x>>y;//輸入最大公約數以及最小公倍數 int v=x*y;//最大值 int s=(int)sqrt(v);//不用重復進行尋找 int n=0; for(int i=x;i<=s;i++) if((v%i==0)//如果最大值能夠整除當前的數,則說明找到了一組可能是真的的解 &&(gcd(v/i,i)==x))//如果另外一個數與當前的數的最大公約數等於輸入的最大公約數 n++;//進行計數 cout<<n*2;// 不進行重復的篩之后要加上另一塊的 return 0; }
②

#include <iostream> #include <cstdio> #define LL long long using namespace std; LL gcd(LL a,LL b) { return b ? gcd(b,a%b) : a; } int main() { LL Gcd,Lcm,ans=0; cin>>Gcd>>Lcm; LL Max=Gcd*Lcm; for(int i=Gcd; i<=Lcm; i++) for(int j=Gcd; j<=Lcm; j++) { if(i*j>Max) continue; if(gcd(i,j)!=Gcd) continue; if(i*j==Max) ans++; } cout<<ans; return 0; }
方法二:分解質因數(最優)
思路:
題目要求最大公約數(gcd)為3,最小公倍數(lcm)為60的兩個數p、q的組數,兩個數都去掉gcd后,即樣例中的3、60變為1、20。
這樣即可變為求gcd為1,lcm為20的兩個數p、q的組數,即找兩個互質的數,他們的乘積為20。
那么可以對20進行質因數分解,得:2、2、5。
盯住其中一個數,從質因數中選擇。由於兩個數要求互質,所以相同的質因數要合並,得到:4、5。
選法有2^2=4種:1,4,5,20。對應的四組答案即:1-20,4-5,5-4,20-1。
乘以gcd得到原來題目答案:3-60,12-15,15-12,60-3。

#include<iostream> #include<cstdio> #include<cmath> using namespace std; int main() { int x,y,z,k=0,i;//k為不同質因數的個數 scanf("%d%d",&x,&y); if(y%x!=0) printf("%d\n",0); else { z=y/x;//除以最大公約數x for(i=2; i<=z; ++i) { //質因數分解 if(z%i==0) { ++k; while(z%i==0)z=z/i;//合並相同的質因數 } } printf("%d\n",int(pow(2,k))); } return 0; }