Codeforces Round #277.5 (Div. 2) C. Given Length and Sum of Digits...(贪心)

1.题目链接:

https://codeforces.com/problemset/problem/489/C

2.题面:

Codeforces Round #277.5 (Div. 2) C. Given Length and Sum of Digits...(贪心)_第1张图片

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 
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];
        }
    }
}

你可能感兴趣的:(Codeforces Round #277.5 (Div. 2) C. Given Length and Sum of Digits...(贪心))