输入数据包含两个整数x, y(2 <= x <= 1 0,000,000, 2 <= y <= 100,000,000),
处理到文件结束
|
18
Vagaa
解题思路:
p*q=gcd(p,q)*lcm(p,q)=y*x;
那p,q的范围是在x到sqrt(y*x)之间的,遍历一遍就好了。
但是,就这么水过去,感觉没什么收获。用一点数论的知识吧~
p=a*x,q=b*x;这是肯定的,都知道的。
p*q=(a*b)*x*x;
p*q=y*x=(a*b)*x*x;
y/x=a*b;
a,b是互质的。关键就要找出a和b
对y/x分解质因子,分解质因子每个质因子都质数。我们应该分解因数。然后暴力搜索一遍
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
using namespace std;
typedef long long int LL;
LL prime[20005];
LL sprime[20005];
int mark[20005];
int tot;
int cnt;
LL x,y;
LL ans;
void eular()
{
memset(mark,0,sizeof(mark));
tot=0;
for(int i=2;i<=20000;i++)
{
if(!mark[i]) prime[tot++]=i;
for(int j=0;j<tot;j++)
{
if(i*prime[j]>20000) break;
mark[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
void Divide(LL n)
{
cnt=0;
LL t=(LL)sqrt(1.0*n);
for(LL i=0;i<tot&&prime[i]<=t;i++)
{
if(n%prime[i]==0)
{
sprime[++cnt]=1;
while(n%prime[i]==0)
{
n/=prime[i];
sprime[cnt]*=prime[i];
}
}
}
if(n>1)
sprime[++cnt]=n;
}
void fun(int x,LL l,LL r)
{
if(x>cnt)
{
//if(l==r) return;
ans=min(ans,l+r);
return;
}
fun(x+1,l*sprime[x],r);
fun(x+1,l,r*sprime[x]);
}
int main()
{
while( scanf("%lld%lld",&x,&y)!=EOF)
{
eular();
if(y%x!=0)
{
printf("Vagaa\n");
continue;
}
Divide(y/x);
ans=1e18;
fun(1,1,1);
printf("%lld\n",ans*x);
}
return 0;
}
|