找数字

找数字

给定一个正整数 m 和一个非负整数 s

请你找到长度为 m 且各位数字之和为 s 的最小和最大非负整数。

要求所求非负整数不得包含前导零。

输入格式

共一行,两个整数 m,s

输出格式

在一行内输出满足条件的最小和最大非负整数。

如果无解,则输出 -1 -1

数据范围

6 个测试点满足 1m3
所有测试点满足 1m1000s900

输入样例1:

2 15

输出样例1:

69 96

输入样例2:

3 0

输出样例2:

-1 -1

 

解题思路

  先考虑没有解的情况。由于有m位数字,每一位最大是9,因此s要满足s9m,否则无解。同时由于非负整数不能含有前导零,因此如果m>1那么s要满足s>1,否则如果s=0,那么m只能为1,这个时候最大值和最小值均取0

  因此无解的情况就是s>9m或者s=0 && m>1

  先看一下怎么求最大值。从高位往低位考虑,对于每一位肯定是能填多大就填多大,因为如果某一位可以填9,那么无论怎么样都一定比填8得到的结果要大。如果当前剩下位的数字之和为s,那么这一位能填的最大数字就是min{9,s}

  然后是最小值。可以从低位往高位考虑,如果想让结果最小那么最后一位越大越好。比如如果最后一位可以填9,如果此时填8的话,那么前面位的数字之和会比填9的要多1。而由于相对于填8的情况,填9的话可以给前面某一位减1,因此填9得到的结果必然比填8得到的结果小。如果当前位不是最高位,那么这一位最大可以填的数字是min{9,s1},减1是因为最高位至少要填1

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main() {
 5     int n, m;
 6     cin >> n >> m;
 7     if (m > 9 * n || !m && n > 1) { // 无解的情况
 8         cout << "-1 -1";
 9         return 0;
10     }
11     string a(n, 0), b(n, 0);
12     int s = m;
13     for (int i = n - 1; i; i--) {   // 从低位往高位构造最小值
14         int t = min(9, s - 1);  // 减1是因为最高位至少是1
15         a[i] = t + '0';
16         s -= t;
17     }
18     a[0] = s + '0'; // 最高位填的数
19     s = m;
20     for (int i = 0; i < n; i++) {   // 从高位往低位构造最大值
21         int t = min(9, s);
22         b[i] = t + '0';
23         s -= t;
24     }
25     cout << a << ' ' << b;
26     
27     return 0;
28 }
复制代码

 

参考资料

  AcWing 4807. 找数字(AcWing杯 - 周赛):https://www.acwing.com/video/4619/

posted @   onlyblues  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示