zoukankan      html  css  js  c++  java
  • HRBUST

    意外
    Time Limit: 1000 MS Memory 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
    ");
    		continue;
        }
    
        Divide(y/x);
         ans=1e18;
    	fun(1,1,1);
        printf("%lld
    ",ans*x);
       }
        return 0;
    }




  • 相关阅读:
    【leetcode】236. 二叉树的最近公共祖先
    【leetcode】230. 二叉搜索树中第K小的元素
    【leetcode】309. 最佳买卖股票时机含冷冻期
    【leetcode】306. 累加数
    【leetcode】304. 二维区域和检索
    spring-framework源码编译及导入
    Java8-函数式接口理解及测试
    Mac编译RocketMQ 4.1.0
    首记
    JS表单验证
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228539.html
Copyright © 2011-2022 走看看