UVa 11889 最小公倍数
第一种(枚举法):
设Ax=By=C
x=C/A与y互质
要使B最小,则y最大
则寻找最大的与x互质的c的约数
另一种做法:
分解质因数,再做一些处理(把指数为0的补上,使A,B,C有相同的a1到an),得
A=a1^x1*a2^x2*...*an^xn
B=a1^y1*a2^y2*...*an^yn
C=a1^z1*a2^z2*...*an^zn
(xi,yi,zi为非负整数)
那么,显然zi=max(xi,yi)(1<=i<=n)
因此,已知xi和zi求yi的方法是:
如果xi=zi,而要使B最小,那么yi=0,或者说把ai^yi直接去掉;
如果xi≠zi,那么yi=zi。
因此,找出C中所有满足xi≠zi的ai^zi,将它们乘起来,就得到B。
由前一种解释得知,要有解,那么C%A为0
令D=C/A=a1^(z1-x1)*...*an^(zn-xn)
显然,如果xi=zi,那么D中ai^(zi-xi)的值就是1,在D中直接去掉
如果xi≠zi,那么D中会出现ai^(zi-xi)(zi-xi>=1)
那么找出d中所有ai,将它们分别做zi次方运算,也能得到B。
有一种简单的做法:
不断使a/=gcd(a,d),最后c/a即为答案,具体见程序
原因:
D中的每个ai,都满足(zi-xi)>=1,也就是对于d中每个ai,ai^zi都会出现在最终求的b中
那么,不断使a/=gcd(a,d),能去掉a中的所有"d中出现过的ai"以及指数,留下的ai^xi都满足xi=zi,
那么,c/a就只剩下了所有满足xi≠zi的ai分别做zi次方运算后相乘的积,也就是所有d中出现过的ai分别做zi次方运算后相乘的积
就是答案
举例:
a=24=2^3*3,c=96=2^5*3,那么d=2^2,不断使a/=gcd(a,d)可以将a中2以及指数去掉,只留下3,那么c/a就是2^5,也就是d中出现的唯一一个ai(3)做了zi(5)次方。
#include<cstdio> int gcd(int a,int b) { int t; while(b!=0) { t=a%b; a=b; b=t; } return a; } int t,a,c,d; int main() { int i,g; scanf("%d",&t); for(i=1;i<=t;i++) { scanf("%d%d",&a,&c); if(c%a!=0) printf("NO SOLUTION\n"); else { d=c/a; g=gcd(a,d); while(g!=1) { a/=g; g=gcd(a,d); } printf("%d\n",c/a); } } return 0; }