数字截断求和 题解

数字截断求和 题解

闲来无事发题解

时间限制: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;
}
相关推荐
Tbisnic4 分钟前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
Brilliantwxx26 分钟前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法
空堂与归1 小时前
用户分群找不到规律?用K-Means聚类算法自动发现数据模式
算法·机器学习·kmeans·聚类
动词ing2 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习2 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
一只小小的芙厨3 小时前
基础数论总结
笔记·学习·算法
夜不会漫长4 小时前
C++入门(1)
开发语言·c++·算法
wen_zhufeng5 小时前
IndexTTS 2.5 技术报告
人工智能·算法·机器学习
大熊背5 小时前
树莓派相机自动白平衡详解(四)
算法·树莓派·白平衡·isppipeline
一米阳光86615 小时前
软考(中级)软件设计师核心笔记(9)算法——背包问题
笔记·算法·职场发展·软考·软件设计师·中级职称