好题 BUPT OJ130 非平方等式

一道关于求解非平方等式的数学问题,寻找最小正整数x,使得x² + s(x)*x - n = 0。其中s(x)是x的十进制数字和,n为给定的大整数。通过分析得出x的范围应在18*9以内,利用x<Sqrt(n)的性质进一步压缩搜索范围,最终通过枚举解决。注意在处理大数据时,int与long long之间的比较要格外小心。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

考虑等式:

x2 + s(xx - n = 0, 

其中x,n是正整数,s(x)是个函数,其值等于x在十进制下所有数字的和。

现给出整数n的大小,请你求出最小的满足条件的正整数x。

输入格式

输入仅包含一个整数n (1 ≤ n ≤ 1018) .

输出格式

如果不存在这样的x,请输出-1;否则请输出满足条件的最小的整数x (x > 0)

输入样例

2

输出样例

1

下课回来就看到这么一道好题, 做了以后深受启发。

题目的大意是找到满足等式的最小值,找不到就返回-1。 看起来不难理解, 但是数据范围却是达到了10^18,用暴力必然TLE。

那么重点就是考虑怎么缩小搜索的范围。

首先我们看到 S(x) 代表x在十进制内各位数字之和,那么事实上 S(x) 的范围是确定的,其上界为所有位数均为9时,即S(x)≤18*9

其次,我们把等式进行转换,x+S(x)=n/x 这个整数方程似乎表明x是n的一个约数,但是求约数也是十分繁琐的过程。

这时我们注意到:n既然可以拆分为 x*(x+S(x)) ,那么x和x+S(x)分别在sqrt(n)的两侧。这是一个很简单的证明,这里也不提。

这个发现对于解决本题的大数据有很大的关键,因为S(x)必然大于0,则x必然小于x+S(x),也就是说x<sqrt(n) 和 x+S(x)>sqrt(n) 恒成立。

所以x的范围其实被压缩到了18*9以内。现在只要进行枚举就能很快的解出此题了。

事实上,我们还可以进一步压缩x的范围,x不会大于sqrt(n),所以不会超过10^9,S(x)的范围也被压缩到了9*9以内。

本题另一个难点就在于和long long有关的判断,int型不能直接和long long型进行比较。所以第一次提交十个测试点只通过四个,这是通过WA才得到的教训,切记,切记。



/*
USER_ID: test#birdstorm
PROBLEM: 130
SUBMISSION_TIME: 2014-03-03 17:23:58
*/
#include <stdio.h>
#include <math.h>
#define MIN(x,y) (x)<(y)?(x):(y)
#define INF 1000000007
  
long long s(long long x)
{
    long long sum=0;
    while(x){
        sum+=x%10;
        x/=10;
    }
    return sum;
}
  
main()
{
    long long x, n, min=INF;
    int i, k;
    scanf("%lld",&n);
    for(i=(int)(sqrt(n)+1),k=1; k<=9*9 && i>0; k++, i--)
        if(((long long)(i)*(long long)(i)+(long long)(s(i)*i))==n) min=MIN(min,i);
    printf("%lld\n",min==INF?-1:min);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值