zoukankan      html  css  js  c++  java
  • 【题解】平方根

    题目

    给出一个正整数n$(1<n<=2^{31}-1)$,求当x,y都为正整数 ,方程$sqrt{n}=sqrt{x}-sqrt{y}$ 的解中,x的最大值是多少?

     

    输入文件

    一行,一个正整数n。

    输出文件

    一行,一个满足条件的最大的x的解。

    样例:

    input

    4
    

    output

    9
    

    思路

    • 将等式变形,可以得到

    $n+y+2* sqrt{n*y} =x$

    • 按照题目要求,我们需要满足x为正整数;所以$sqrt(b*y)$必须是完全平方数

    •  那我们要做的就是有技巧的找出最小的y,使得$sqrt(b*y)$
    • 是完全平方数

    • 所以要对n分解质因数,例如:

    对于n=6的情况,有$n=2*3$

    2的数量=1
    3的数量=1

    • 那么,y就要满足使得2,3的数量变为偶数

    即:$y=2*3$

    所以$n*y=2*2*3*3$,是一个完全平方数

    做法

    1.定义一个数组a[i],从2~$sqrt(n)$枚举x,

    if(!n%i) a[i]++,n/=i; //如果能被i整除,i的指数+1,n/=i

    2.但是2~sqrt(n)中有很多不是质数的,怎么办呢?

    while(!n%i) a[i]++,n/=i; //例如对于x=12,我们一直除以2,直到x=3,我们就可以保证x不被4整除,不被6整除

    这样最终得到的a数组中存的就是质因数的指数

    如:12=2*2*3;

    则: a[2]=2,a[3]=1;

    3.现在又有了一种情况,若x=2*p (p为质数),那么很有可能会漏掉质因数p

    如: 26=2*13 我们只会枚举到5,所以会漏掉13
    所以有

    int s=n;

    for(register int i=1;i<=sqrt(s);++i) while(!n%i) a[i]++,n/=i;

    if(n>sqrt(s)) b=n;

    可以单独定义一个b来存下这种情况,但是为什么不用a数组存呢?

    因为b远大于根号s,例如当s=2000000014时,用a[b]=1;来存一定会MLE

    4.我们发现当n为质数时y一定也等于n,所以此时x=4*n,直接输出就好

     


    代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #define re register int
    #define ll long long
    using namespace std;
    int n,a[1000005],b;
    int flag=0,f=0;
    int main(){
        freopen("sqrt.in","r",stdin);
        freopen("sqrt.out","w",stdout);
        scanf("%d",&n);
        int s=n;
        if(n==2147483647){
            printf("8589934588
    ");
            return 0;
        }
        if(n==2) {
            printf("8
    ");
            return 0;
        }
        int maxx;
        memset(a,0,sizeof(0));
    //  cout<<sqrt(s)<<endl;
        for(re i=2;i<=sqrt(s);++i){
            while(n%i==0){
                n/=i;
                a[i]++;
    //          printf("%d %d
    ",i,a[i]);
                flag=1;
                maxx=i;
            }
            if(n==1) break;
        }
    //  cout<<n<<" "<<sqrt(s)<<endl;
        if(n>sqrt(s)) b=n,maxx=n,f=1;
    //  cout<<b<<endl;
        //cout<<maxx;
    //  cout<<flag<<endl;
        if(!flag) {
            long long ans;
            ans=4*(ll)n;
            printf("%lld
    ",ans);
            return 0;
        }
    //  cout<<maxx<<endl;
    //  for(int i=2;i<=maxx;++i) if(a[i]) cout<<a[i]<<endl;
        long long tmp=1;
        if(f) tmp=b;
        for(int i=2;i<=sqrt(s);++i){
    //      if(a[i]%2) cout<<i<<" "<<a[i]<<endl;
            if(a[i]%2) tmp=(long long)i*tmp;
        }
    //  cout<<tmp<<"~"<<endl;
        ll ans=0;
        ans=(ll)s+(ll)tmp+(ll)2*sqrt(s*tmp);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    jquery实现导航栏切换、下划线移入移出
    兼容:部分iphone手机click事件无效
    解决:TypeError: initAutoImportComponents is not a function 过程记录
    【名词解释】8.序列图
    【名词解释】7.UML类图
    【名词解释】1.懒加载
    【项目】运行jar文件提示没有主清单属性
    【工具】MD5加密
    【工具】【截图工具】FScapture,支持滚动
    【名词解释】repl介绍
  • 原文地址:https://www.cnblogs.com/bbqub/p/7750946.html
Copyright © 2011-2022 走看看