CodeForces 509C Sums of Digits(贪心乱搞)题解

题意:a是严格递增数列,bi是ai每一位的和,告诉你b1~bn,问你怎样搞才能让an最小

思路:让ai刚好大于ai-1弄出来的an最小。所以直接模拟贪心,如果当前位和前一个数的当前位一样并且后面还能生成比前一个数大的数,那么就和前一个数保持一致,否则当前位 = 前一个数当前位+ 1,后面的位数按照最小方式排列。如果排到最后每一位都和前面一个数一致,就把剩余的b从最小的一位一直加满9。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 300 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int b[maxn], ans[maxn][maxn + 200], cnt[maxn];
void solve1(int i){
    cnt[i] = 0;
    while(b[i] > 9){
        ans[i][cnt[i]++] = 9;
        b[i] -= 9;
    }
    ans[i][cnt[i]++] = b[i];
}
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &b[i]);
    }

    solve1(1);
    for(int i = 2; i <= n; i++){
        if(b[i] - 9 * cnt[i - 1] > 0){
            solve1(i);
        }
        else{
            if(b[i] <= ans[i - 1][cnt[i - 1] - 1]){
                cnt[i] = cnt[i - 1] + 1;
                ans[i][cnt[i] - 1] = 1;
                b[i]--;
                for(int j = 0; j < cnt[i] - 1; j++){
                    if(b[i] >= 9){
                        ans[i][j] = 9;
                        b[i] -= 9;
                    }
                    else if(b[i] > 0){
                        ans[i][j] = b[i];
                        b[i] = 0;
                    }
                    else ans[i][j] = 0;
                }
            }
            else{
                cnt[i] = cnt[i - 1];
                for(int j = cnt[i] - 1; j >= 0; j--){
                    if(j != 0){
                        if(b[i] - ans[i - 1][j] <= ans[i - 1][j - 1]){
                            ans[i][j] = ans[i - 1][j] + 1;
                            b[i] -= ans[i][j];
                            while(ans[i][j] > 9){
                                b[i] += ans[i][j] - 1;
                                j++;
                                if(j == cnt[i]){
                                    ans[i][j] = 0;
                                    cnt[i]++;
                                }
                                ans[i][j]++;
                            }

                            for(int k = 0; k < j; k++){
                                if(b[i] >= 9){
                                    ans[i][k] = 9;
                                    b[i] -= 9;
                                }
                                else if(b[i] > 0){
                                    ans[i][k] = b[i];
                                    b[i] = 0;
                                }
                                else ans[i][k] = 0;
                            }
                            break;
                        }
                        else{
                            ans[i][j] = ans[i - 1][j];
                            b[i] -= ans[i][j];
                        }
                    }
                    else{
                        ans[i][j] = ans[i - 1][j];
                        b[i] -= ans[i][j];
                    }
                }
                if(b[i] > 0){
                    for(int j = 0; j < cnt[i] && b[i] > 0; j++){
                        if(b[i] > 9 - ans[i][j]){
                            b[i] -= 9 - ans[i][j];
                            ans[i][j] = 9;
                        }
                        else{
                            ans[i][j] += b[i];
                            b[i] = 0;
                        }
                    }
                }
            }
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = cnt[i] - 1; j >= 0; j--)
            printf("%d", ans[i][j]);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/KirinSB/p/10395539.html