2021.10.20队内周赛第一题,2021.10.27补题



489C - Given Length and Sum of Digits...(源地址自​​⇔CF489B​​)

Problem

489C - Given Length and Sum of Digits...(数学规律+构造性算法+贪心+普及级)_数学、规律(math)

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.27 成文