HRBUST - 1153 意外 HRBUST - 1153 (数论)

意外
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 326(87 users)Total Accepted: 97(63 users)Rating: Special Judge: No
Description

静竹以为从此过上了幸福的日子,没想到数学的好友欧几里德心存不满总是暗中使坏!有一天,欧几里德在静竹经常与数学相见的地方放了一条毒蛇,一不小心静竹就中毒了。还有人性的是,欧几里德把解药放到了一个密码箱里,但是密码呢必须通过箱子上面的两个数来计算出,数学能够把静竹成功解救吗?

Input

输入数据包含两个整数x, y(2 <= x <= 1 0,000,000, 2 <= y <= 100,000,000),
处理到文件结束

Output

对于每组输入的x,y输出一个整数表示密码并换行
密码是由p+q的和组成,其中p,q满足
1) p q都是正整数
2) GCD(p, q) = x;
3) LCM(p, q) = y.
由于存在多组解,输出p+q和最小的那种情况即可。
如果p, q不存在,输出Vagaa

Sample Input
3 15
23 45
Sample Output
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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值