1 条题解

  • 0
    @ 2026-5-2 18:50:52

    题目分析

    k=0k = 0,答案显然为 00

    k>0k > 0,设序列的第 x+1x + 1 项为平方数,则存在正整数 yy,使得 k+x2=y2k + x^2 = y^2,于是 k=y2x2=(y+x)(yx)k = y^2 - x^2 = (y + x)(y - x),于是枚举 kk 的所有不超过 k\sqrt{k} 的正因数 ii,那么就可以令 y+x=i,yx=k÷iy + x = i , y - x = k \div i,解得 y=(i+k÷i)÷2y = (i + k \div i) \div 2,最后取所有 yy 的最小值即可。

    k<0k < 0,设序列的第 x+1x + 1 项为平方数,则存在正整数 yy,使得 k+x2=y2- \left| k \right| + x^2 = y^2,于是 k=x2y2=(x+y)(xy)\left| k \right| = x^2 - y^2 = (x + y)(x - y),于是枚举 k\left| k \right| 的所有不超过 k\sqrt{\left| k \right|} 的正因数 ii,那么就可以令 x+y=k÷i,xy=ix + y = \left| k \right| \div i , x - y = i,解得 $y = \left| k \right| \div i - (i + \left| k \right| \div i) \div 2$,最后取所有 yy 的最小值即可。注意这里不令 x+y=i,xy=k÷ix + y = i , x - y = \left| k \right| \div i 的原因是这种情况下解得 y=i(i+k÷i)÷2y = i - (i + \left| k \right| \div i) \div 2,但这是负数(因为 iki \le \sqrt{\left| k \right|})。

    注意判断无解。时间复杂度为 O(k)O(\sqrt{\left| k \right|})

    参考代码

    #include<iostream>
    #define int long long
    using namespace std;
    int k;
    signed main(){
    	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	cin>>k;
    	if(k==0) cout<<0;
    	else if(k>0){
    		int ans=1e18;
    		for(int i=1;i*i<=k;i++){
    			if(k%i==0){
    				if((i+k/i)%2==0) ans=min(ans,(i+k/i)/2);
    			}
    		}
    		if(ans==1e18) cout<<"none";
    		else cout<<ans;
    	}else{
    		k*=-1;
    		int ans=1e18;
    		for(int i=1;i*i<=k;i++){
    			if(k%i==0){
    				if((i+k/i)%2==0) ans=min(ans,k/i-(i+k/i)/2);
    			}
    		}
    		if(ans==1e18) cout<<"none";
    		else cout<<ans;
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    10285
    时间
    1000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者