数字截断求和 题解

数字截断求和 题解

闲来无事发题解

时间限制: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;
}
相关推荐
AZaLEan__1 小时前
多源 BFS
java·开发语言·算法
smith成长之旅2 小时前
07 | Mem0 框架分析:三路信号融合——语义 + BM25 + Entity Boost 的混合检索
python·算法
wabs6662 小时前
关于贪心算法章节的【有两个维度问题】的自我总结
算法·贪心算法
未若君雅裁2 小时前
算法复杂度与数据结构:Java 集合篇的第一块基石
java·数据结构·算法
春日见3 小时前
五分钟入门 强化学习---Q-Learning算法与实现
人工智能·python·深度学习·算法·机器学习·计算机视觉
Zldaisy3d3 小时前
全球唯一仿真驱动自适应扫描路径新版本发布,金属3D打印工艺开发进入算法时代
算法·3d
小江的记录本3 小时前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
故事和你914 小时前
洛谷-【动态规划2】线性状态动态规划4
开发语言·数据结构·c++·算法·动态规划·图论
不吃土豆的马铃薯4 小时前
Socket 网络编程实战教程
linux·服务器·开发语言·网络·c++·算法