找数字
找数字
给定一个正整数 和一个非负整数 。
请你找到长度为 且各位数字之和为 的最小和最大非负整数。
要求所求非负整数不得包含前导零。
输入格式
共一行,两个整数 。
输出格式
在一行内输出满足条件的最小和最大非负整数。
如果无解,则输出 -1 -1。
数据范围
前 个测试点满足 。
所有测试点满足 ,。
输入样例1:
2 15
输出样例1:
69 96
输入样例2:
3 0
输出样例2:
-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/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17113346.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效