数字截断求和 题解

数字截断求和 题解

闲来无事发题解

时间限制:1000ms 内存限制:128MB 栈限制:128MB

题目描述

对于一个正整数 X1,不断删除其最后一位数字,依次得到 X2、X3、...、Xn,直到只剩一位数字为止。令 Y = X1 + X2 + ... + Xn。

例如:X1 = 509 时,X2 = 50,X3 = 5,则 Y = 509 + 50 + 5 = 564。

现在给定 Y,请求出原始的 X1。若不存在满足条件的 X1,输出 -1。数据保证若有解则解唯一。

输入格式

一行,一个正整数Y。

输出格式

一行,一个整数X1,或者输出-1。

样例

样例 1 输入:

564

样例 1 输出:

509

样例 2 输入:

565

样例 2 输出:

-1

样例 3 输入:

137174210616796

样例 3 输出:

123456789555123

样例解析

样例1:509 + 50 + 5 = 564,所以X1 = 509。

样例2:不存在满足条件的X1,输出-1。

样例3:大数据测试。

数据规模

1 ≤ Y ≤ 10^15


所谓不开 long long冒青烟,我们观察题目:

找到一个数,每次/10后增加起来=y就是答案

样例解释:

样例3:123456789555123+12345678955512+1234567895551+123456789555+12345678955+1234567895+123456789+12345678+1234567+123456+12345+1234+123+12+1=137174210616796

思路1 暴力枚举

万事皆暴力,我们从1枚举到y,每次都尝试一次,再写一个函数去判断即可

函数判断:

用一个数(i)每次/10再用sum加起来

函数代码:

cpp 复制代码
long long sumhe(long long x){
    long long tmp=0;
    while(x>0){
        tmp+=x;
        x/=10;
    }
    return tmp;
}

枚举代码:

cpp 复制代码
cin>>y;
    for(long long i=1;i<=y;i++){
        if(sumhe(i)==y){
            cout<<i;
            return 0;
        }
    }

但是这样子当 y = 101510^{15}1015 时就会超时,因为c++ 1秒只能运行 10910^{9}109 / 1e91e91e9 次

数字截断求和 题解

闲来无事发题解

时间限制:1000ms 内存限制:128MB 栈限制:128MB

题目描述

对于一个正整数 X1,不断删除其最后一位数字,依次得到 X2、X3、...、Xn,直到只剩一位数字为止。令 Y = X1 + X2 + ... + Xn。

例如:X1 = 509 时,X2 = 50,X3 = 5,则 Y = 509 + 50 + 5 = 564。

现在给定 Y,请求出原始的 X1。若不存在满足条件的 X1,输出 -1。数据保证若有解则解唯一。

输入格式

一行,一个正整数Y。

输出格式

一行,一个整数X1,或者输出-1。

样例

样例 1 输入:

564

样例 1 输出:

509

样例 2 输入:

565

样例 2 输出:

-1

样例 3 输入:

137174210616796

样例 3 输出:

123456789555123

样例解析

样例1:509 + 50 + 5 = 564,所以X1 = 509。

样例2:不存在满足条件的X1,输出-1。

样例3:大数据测试。

数据规模

1 ≤ Y ≤ 10^15


所谓不开 long long冒青烟,我们观察题目:

找到一个数,每次/10后增加起来=y就是答案

样例解释:

样例3:123456789555123+12345678955512+1234567895551+123456789555+12345678955+1234567895+123456789+12345678+1234567+123456+12345+1234+123+12+1=137174210616796

思路1 暴力枚举

万事皆暴力,我们从1枚举到y,每次都尝试一次,再写一个函数去判断即可

函数判断:

用一个数(i)每次/10再用sum加起来

函数代码:

cpp 复制代码
long long sumhe(long long x){
    long long tmp=0;
    while(x>0){
        tmp+=x;
        x/=10;
    }
    return tmp;
}

枚举代码:

cpp 复制代码
cin>>y;
    for(long long i=1;i<=y;i++){
        if(sumhe(i)==y){
            cout<<i;
            return 0;
        }
    }

但是这样子当 y = 101510^{15}1015 时就会超时,因为c++ 1秒只能运行 10910^{9}109 / 1e91e91e9 次

思路2 二分答案

二分查找科普环节(可跳过)

二分查找就像一种猜数游戏,能够大大优化枚举时间的复杂度

像我们玩的猜数游戏:

A :数字炸弹在1100内!

B :我猜50

A :小了

B :75?

A :大了

B :62?

A :还是大了!

B56?

A :小了!

B :59?

A :大了!

B58

A :蒸蚌!

这就是一次二分查找过程,对比:

枚举:1 -> 2 -> 3 ...-> 答案

二分查找:中间值 ->(中间值调整) 中间值 -> ... ->答案

相比之下,猜1~100,枚举需要100次,而二分查找至于用7次

具体思路:设定两个指针 l,r分别指向左边界与右边界,再设一个mid=(l+r)/2,如果小了就l=mid+1,否则r=mid-1

二分AC代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long y;
long long sumhe(long long x){
    long long tmp=0;
    while(x>0){
        tmp+=x;
        x/=10;
    }
    return tmp;
}
int main(){
    cin>>y;
    long long l=1,r=y,mid=0,tmp=-1;
    while(l<=r){
        mid=(l+r)/2;
        if(sumhe(mid)==y){
            tmp=mid;
            break;
        }
        if(sumhe(mid)<y){
            l=mid+1;
        }else if(sumhe(mid)>y){
            r=mid-1;
        }
    }
    cout<<tmp;
    return 0;
}
```![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2FC%3A%5CUsers%5CAdministrator%5CAppData%5CRoaming%5Cmarktext%5Cimages%5C2026-05-30-11-46-12-image.png%3Fmsec%3D1780112772466&pos_id=img-Da4VCPtH-1780113426665)

## 思路2 二分答案

### 二分查找科普环节(可跳过)

二分查找就像一种猜数游戏,能够大大优化枚举时间的复杂度

像我们玩的猜数游戏:

**A** :数字炸弹在```1```到```100```内!

**B**:我猜```50```

**A** :小了

**B** :```75```?

**A** :大了

**B** :```62```?

**A** :还是大了!

**B** :```56```?

**A** :小了!

**B** :```59```?

**A** :大了!

**B**:```58```

**A** :蒸蚌!

这就是一次二分查找过程,对比:

枚举:1 -> 2 -> 3 ....-> 答案

二分查找:中间值 ->(中间值调整) 中间值 -> ... ->答案

相比之下,猜1~100,枚举需要100次,而二分查找至于用7次

具体思路:设定两个指针 l,r分别指向左边界与右边界,再设一个```mid=(l+r)/2```,如果小了就```l=mid+1```,否则```r=mid-1```

### 二分AC代码

```cpp
#include<bits/stdc++.h>
using namespace std;
long long y;
long long sumhe(long long x){
    long long tmp=0;
    while(x>0){
        tmp+=x;
        x/=10;
    }
    return tmp;
}
int main(){
    cin>>y;
    long long l=1,r=y,mid=0,tmp=-1;
    while(l<=r){
        mid=(l+r)/2;
        if(sumhe(mid)==y){
            tmp=mid;
            break;
        }
        if(sumhe(mid)<y){
            l=mid+1;
        }else if(sumhe(mid)>y){
            r=mid-1;
        }
    }
    cout<<tmp;
    return 0;
}
相关推荐
JieE21221 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2122 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2123 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2123 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术3 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦3 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050733 天前
(一)小红的数组操作
算法·编程语言