【题解】平方根

题目

给出一个正整数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;
}
原文地址:https://www.cnblogs.com/bbqub/p/7750946.html