UVa 11889 最小公倍数

vjudge

第一种(枚举法):

设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;
}
posted @ 2017-07-24 16:02  hehe_54321  阅读(180)  评论(0编辑  收藏  举报
AmazingCounters.com