CodeForces489C. Given Length and Sum of Digits 【dp 贪心】

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You have a positive integer m and a non-negative integer s. Your task is to find the smallest and the largest of the numbers that have length m and sum of digits s. The required numbers should be non-negative integers written in the decimal base without leading zeroes.

Input
The single line of the input contains a pair of integers m, s (1 ≤ m ≤ 100, 0 ≤ s ≤ 900) — the length and the sum of the digits of the required numbers.

Output
In the output print the pair of the required non-negative integer numbers — first the minimum possible number, then — the maximum possible number. If no numbers satisfying conditions required exist, print the pair of numbers “-1 -1” (without the quotes).

Examples
inputCopy
2 15
output
69 96
inputCopy
3 0
output
-1 -1

两种处理思路:
1.最大值和最小值分别处理。最大值就是正着放置,尽可能填9。最小值需要注意开头不能为0,所以先设置第一位为1,同时总和减一,保证之后的更新不会出现第一位为0的情况。
2**第二种方法很巧妙。**最大值和最小值之间是有关系的。如果取得最大值,最末尾不为0,那么倒置即为最小值。开始不考虑首位,按贪心同第一种方法求,尽可能填9.为了避免直接倒置输出倒置最小值首位为0.
利用 for(int k = 0;!num[k];k++); 注意分号。这条语句是为了找到从左到右第一个不为0的数的位置(最高非零位)。然后 num[0]++; num[k]–; 如果第一位为0 那么让它加一满足条件,同时让最高非零位减一,保证总和为s。如果首位本身不为0,那么跳出循环时k==0.
那么之后进行num[0]++; num[k]–; 相当于每一位都没有变化。

#include
#include
#include
using namespace std;
int num[105];
int  main()
{
    int m,s;
    cin>>m>>s;
    num[0] = 1;
    int sum = s-1;
    //找到最小值 倒着放置 低位尽可能大 
    if(s==0&&m ==1) 
    {
        cout<<0<<' '<<0<else if(m*91)//s<1成立的情况只有上面m==1时 否则都是错误的
    {
        cout<<-1<<' '<<-1<else
    {
        for(int i = m-1;i>=0;i--)
        {
            if(9-num[i]9-num[i];
                num[i] = 9;
            }
            else//该位已经不足够置成9 就把剩余的sum放入 
            {
                num[i] +=sum;
                break;
            }

        }
        for(int i = 0;icout<cout<<' ';
        //最大值 正向放置 高位尽可能大 
        memset(num,0,sizeof(num));
        sum = s;
        for(int i = 0;iif(9-num[i]9-num[i];
                num[i] = 9;
            } 
            else
            {
                num[i] += sum;
                break;
            }
        } 
        for(int i = 0;icout<cout<return 0;
}

第二种方法

#include
#include
using namespace std;
int num[105];
int main()
{
    int m,s;
    while(scanf("%d%d",&m,&s)!=EOF)
    {
        if(m==1&&s==0)
        {
            cout<<0<<' '<<0<continue;
        }
        else if(m*91)
        {
            cout<<-1<<' '<<-1<continue;
        }
        for(int i = m-1;i>=0;i--)
        {
            num[i] = min(s,9);
            s -= min(s,9);
        }
        int k;
        for(k = 0;!num[k];k++);//这一步是要找到从左到右第一个不为0的位置 
        num[0]++; 
        num[k]--;//如果第一位就不是0,那么k=0又将第一位恢复不影响
        for(int i = 0;icout<cout<<' ';
        num[0]--;
        num[k]++;
        for(int i = m-1;i>=0;i--)
        {
            cout<cout<return 0;
}

你可能感兴趣的:(CodeForces489C. Given Length and Sum of Digits 【dp 贪心】)