1. 程式人生 > >codeforce 509C (很有趣的貪心模擬構造)

codeforce 509C (很有趣的貪心模擬構造)

C. Sums of Digits time limit per test 2 seconds memory limit per test 256 megabytes

Vasya had a strictly increasing sequence of positive integersa1, ...,an. Vasya used it to build a new sequenceb1, ...,bn, wherebi is the sum of digits ofai's decimal representation. Then sequenceai got lost and all that remained is sequenceb

i.

Vasya wonders what the numbers ai could be like. Of all the possible options he likes the one sequence with the minimum possible last numberan. Help Vasya restore the initial sequence.

It is guaranteed that such a sequence always exists.

Input

The first line contains a single integer number n

(1 ≤ n ≤ 300).

Next n lines contain integer numbersb1, ...,bn  — the required sums of digits. Allbi belong to the range1 ≤ bi ≤ 300.

Output

Print n integer numbers, one per line — the correct option for numbersai, in order of following in sequence. The sequence should be strictly increasing. The sum of digits of thei

-th number should be equal tobi.

If there are multiple sequences with least possible numberan, print any of them. Print the numbers without leading zeroes.

Sample test(s) Input
3
1
2
3
Output
1
2
3
Input
3
3
2
1
Output
3
11
100

題目大意:給你一組數字每位的和組成的序列,現在要找到原數字組成的序列,該序列是一個嚴格遞增序列, 要求最後一個數字是在所有滿足條件的序列中最小的

題目分析:我們根據上一個數字來推出下一個數字,方法是先計算當前位和與前一個位和的差

1.如果差值大於0,直接從上一個數字的最低位開始累加差值,滿10進1

2.如果差值小於0,則先從上一個數字的低位依次往後累加差值,直到差值大於0,這裡的操作相當於減去上一位數字多出來的部分再進行1操作,舉個例子

5
6
10
18
16
7

答案是

6
19
99
169
205

首先 第一個數字肯定不變,接著10,10-6=4>0,因此我們直接從6開始列舉6+3=9因為4-3=1差一位則進位,得到19

18-10=8>0從19的最低位列舉,因為最低位為9,因此從十位列舉,十位是1,加上差值8即十位變成9,得到99

18-16=-2<0 這時要先讓差值大於0,在99的最低位9減去2,得到7,將最低位歸0,因為第二位也是9,還要進位,進位的時候差值要累加9得到16,十位0,最後我們其實把問題轉變為,從100開始找十位和個位和為15的最小數,直接從低位列舉就行了,因為15>9,所以個位就是9,十位是15-9=6,最後得169,一開始得到7時因為97<99,因此我們必須要進位,還有將最低位歸0得操作是因為我們要找的是大於前一個數的最小數,因此要從0開始列舉

7-16=-9<0 這時要先讓差值大於0,在169最低位9減去9,得到0,將最低位歸0,這時候d=0,則加上十位6,十位歸0,百位加1,差值減1,轉變為從200開始找十位和個位和為5的最小數,列舉得到205.

#include <cstdio>
#include <cstring>
int digit[1000], len = 0;

void next(int d)
{
    for(int i = 1; d > 0; i++) //從低位列舉
    {
        while(d > 0 && digit[i] < 9)
        {
            d--;
            digit[i]++;
        }
        len = i > len ? i : len; //進位的時候要注意更改位數
    }
}

int main()
{
    int n, b[400];
    scanf("%d", &n);
    b[0] = 0;
    for(int i = 1; i <= n; i++)
        scanf("%d", &b[i]);
    for(int i = 1; i <= n; i++)
    {
        int d = b[i] - b[i - 1];
        if(d > 0)
            next(d);
        else 
        {
            for(int i = 1; ; i++)
            {
                len = i > len ? i : len;
                if(d > 0 && digit[i] < 9)
                {
                    d--;
                    digit[i]++;
                    next(d);
                    break;
                }
                d += digit[i];
                digit[i] = 0;
            }
        }
        for(int i = len; i >= 1; i--)
            printf("%d", digit[i]);
        printf("\n");
    }
}