489C - Given Length and Sum of Digits...(数学规律+构造性算法+贪心+普及级)
489C - Given Length and Sum of Digits...(源地址自⇔CF489C)
Problem
tag:
⇔数学规律、⇔构造性算法、⇔贪心、⇔普及级(*1400)
题意:
给定 \(m\) 和 \(s\) 两个数字——要求构造一个 \(m\) 位数,其各位数之和为 \(s\) 。
输出满足上面两个条件的数字中,最小的那个和最大的两个。
思路:
这道题其实很考验逻辑思维,首先应当考虑的是怎样构造才能得到最小、最大值。
最小值的构成应当是:第 \(1\) 位必定为 \(0\) ,此后尽可能的保证多的 \(0\) ,最后几位补上 \(9\) 。最大值的构成应当是:前面几位尽可能的保证多的 \(9\) ,最后几位补上 \(0\) 。
故 \(s\) 的范围是:\(1\) 到 \(9*m\) ,范围外的均判错。
AC代码:
//A WIDA Project
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+5;
long long n, ans[MAX], num, m, s;
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> m >> s;
if(m == 1 && s == 0){
cout << "0 0";
}else if(1 <= s && s <= m * 9) {
num = s - 1;
for(int i = 1; i <= m; i ++) {
if(num >= 9) {
ans[m - i + 1] = 9;
num -= 9;
}else if(num > 0) {
ans[m - i + 1] = num;
num = 0;
}else if(num == 0) {
ans[m - i + 1] = 0;
}
}
ans[1] ++;
for(int i = 1; i <= m; i ++) cout << ans[i];
cout << " ";
num = s;
for(int i = 1; i <= m; i ++) {
if(num >= 9) {
cout << 9;
num -= 9;
}else if(num > 0) {
cout << num;
num = 0;
}else if(num == 0) {
cout << 0;
}
}
}else {
cout << "-1 -1" << endl;
}
return 0;
}
错误次数:3次,(补题)3次
原因:三次均为方向性错误。
原因:处理最小值的时候,第一位直接处理为1。
原因:没有特判1,0这种情况
原因:1,0这种情况特判错误
文 / WIDA
2021.10.27成文
首发于WIDA个人博客,仅供学习讨论
更新日记:
2021.10.30 修改tag、修改链接
2021.10.27 成文