1.题目链接:
https://codeforces.com/problemset/problem/489/C
2.题面:
3.翻译:
您有一个正整数m和一个非负整数s。 您的任务是找到长度为m且位数为s的最小和最大数字。 所需数字应为以十进制为基数且不带前导零的非负整数。
输入值
输入的单行包含一对整数m,s(1≤m≤100,0≤s≤900)—长度和所需数字的位数之和。
输出量
在输出中,输出一对必需的非负整数-首先是最小可能的数字,然后是最大可能的数字。 如果不存在满足所需条件的数字,则打印数字对“ -1 -1”(不带引号)。
例子
inputCopy
2 15
outputCopy
69 96
inputCopy
3 0
outputCopy
-1 -1
4.思路:
这道题目我们首先要考虑的是输出-1 -1的情况,我们可以知道,只要总和大于1就一定可以组成一个n位数的数字,但是当s小于1的时候,只有当n为1的时候才一定可以组成,其他的都无法组成。所以第一种满足的情况出来了:s<1并且n>=2,第二种就是s总数比每一位都取9的情况还要大,这样子也肯定不满足题意,所以最后输出-1 -1的情况就是s<1并且n>=2或者s>9*n。这是第一个要解决的问题。后面取最大数和最小数,最大数很容易取,我们只有尽可能把高位往高了取,但是不能取大于9的数字就行了。而最小值我们就要考虑一种问题,不能直接把最大数逆序输出就行,以为假如最大数的最后一位为0,你直接逆序的话那么就不满足位数,所以我们一定要使得最小值的首位不为0,那么我们就从高位开始扫,一旦出现一个大于0的数字就把这个数字减1加到第一位,这样子在满足位数的同时也保证了数的最小,这就是这道题目的贪心思想。
5.参考代码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 7;
int a[MAXN];
int b[MAXN];
int main()
{
int n, s;
cin >> n >> s;
if ((s < 1 && n >= 2) || (s > 9 * n))
{
cout << "-1 -1";
}
else
{
for (int i = n; i >= 1; i--)
{
a[i] = min(s, 9);//每次取最大的值,但是不能大于9
s = s - a[i];//取了之后总数减去
}
for (int i = 1; i <= n; i++)
{
b[i] = a[i];
}
if (b[1] == 0)//如果最小值的首位为0的话,我们要使得不为0
{
for (int i = 2; i <= n; i++)
{
if (b[i] != 0)//从大位开始判断,一旦存在一个大于0的存在就减去一加到首位中,就实现了满足位数,同时位数满足的最小数
{
b[i]--;
b[1]++;
break;
}
}
}
for (int i = 1; i <= n; i++)
{
cout << b[i];
}
cout << " ";
for (int i = n; i >= 1; i--)
{
cout << a[i];
}
}
}