[codeforces 509]C. Sums of Digits

试题描述

Vasya had a strictly increasing sequence of positive integers a1, ..., an. Vasya used it to build a new sequence b1, ..., bn, where bi is the sum of digits of ai‘s decimal representation. Then sequence ai got lost and all that remained is sequence bi.

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

It is guaranteed that such a sequence always exists.

输入

The first line contains a single integer number n (1 ≤ n ≤ 300).

Next n lines contain integer numbers b1, ..., bn  — the required sums of digits. All bi belong to the range 1 ≤ bi ≤ 300.

输出

Print n integer numbers, one per line — the correct option for numbers ai, in order of following in sequence. The sequence should be strictly increasing. The sum of digits of the i-th number should be equal to bi.

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

输入示例

3
3
2
1

输出示例

3
11
100

数据规模及约定

见“输入

题解

显然是贪心,尽量使当前数接近上一个数,且大于等于上一个数 + 1. 搞一个类似高精度运算的模拟。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
    if(Head == Tail) {
        int l = fread(buffer, 1, BufferSize, stdin);
        Tail = (Head = buffer) + l;
    }
    return *Head++;
}
int read() {
    int x = 0, f = 1; char c = getchar();
    while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
    while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
    return x * f;
}

#define maxn 310
int n, B[maxn], num[maxn][maxn], len[maxn];

int main() {
	n = read();
	for(int i = 1; i <= n; i++) B[i] = read();

	len[0] = 1;
	for(int i = 1; i <= n; i++) {
		num[i-1][1]++;
		for(int j = 1; j <= len[i-1]; j++) {
			num[i-1][j+1] += num[i-1][j] / 10;
			num[i-1][j] %= 10;
		}
		for(int j = len[i-1] + 1; num[i-1][j]; j++) {
			num[i-1][j+1] += num[i-1][j] / 10;
			num[i-1][j] %= 10;
			len[i-1] = j;
		}
		int tot = B[i], s = 0;
		for(int j = 1; j <= len[i-1]; j++) s += num[i-1][j];
		if(s == tot) memcpy(num[i], num[i-1], sizeof(num[i-1])), len[i] = len[i-1];
		else {
			len[i] = 0;
			for(int j = len[i-1]; j; j--)
				if(tot > num[i-1][j]) {
					len[i] = max(len[i], j);
					num[i][j] = num[i-1][j];
					tot -= num[i][j];
				}
				else {
					len[i] = max(len[i], j + 1);
					num[i][j+1]++; tot--;
					for(int k = j; k; k--) num[i][k] = 0;
					break;
				}
			for(int j = 1; j <= len[i]; j++) {
				num[i][j+1] += num[i][j] / 10;
				num[i][j] %= 10;
			}
			for(int j = len[i] + 1; num[i][j]; j++) {
				num[i][j+1] += num[i][j] / 10;
				num[i][j] %= 10;
				len[i] = j;
			}
			tot = B[i];
			for(int j = 1; j <= len[i]; j++) tot -= num[i][j];
//			for(int j = len[i]; j; j--) printf("%d", num[i][j]); putchar(‘\n‘);
			for(int j = 1; tot; j++) {
//				printf("%d(%d) ", tot, num[i][j]);
				if(tot >= 9 - num[i][j]) tot -= (9 - num[i][j]), num[i][j] = 9;
				else num[i][j] += tot, tot = 0;
				len[i] = max(len[i], j);
			}
//			putchar(‘\n‘);
		}
		for(int j = len[i]; j; j--) printf("%d", num[i][j]); putchar(‘\n‘);
	}

	return 0;
}
/*
5
30
29
28
42
11
*/
时间: 2024-08-28 19:13:45

[codeforces 509]C. Sums of Digits的相关文章

codeforces 509C Sums of Digits

codeforces 509C Sums of Digits 题意: 给出n个数字各位的加和bi,求一个严格递增的数列.要求最后一个数字最小. 如: 3 2 1 -> 3 11 100 限制: 1 <= n <= 300; 1 <= bi <=300 思路: 贪心,要求最后一个数字最小,只要保证一路过来的数字都尽量小就行. 令d=b[i]-b[i-1], 如果d>0,则从最低位填起,尽量把低位填到9 如果d<=0,则先从低位开始进位,使得d>0,然后就可以转

CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforces Round 26 题意: 设定数组 y = f(x) 使得 y[i] = sum(x[j]) (0 <= j < i) 求初始数组 A0 经过多少次 f(x) 后 会有一个元素 大于 k 分析: 考虑 A0 = {1, 0, 0, 0} A1 = {1, 1, 1, 1} -> {C(

Codeforces 126D Fibonacci Sums 求n由任意的Sum(fib)的方法数 dp

题目链接:点击打开链接 题意: 给定一个数n 问把这个数拆成多个不相同的fibonacci数 有多少种拆法 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<m

Codeforces 509C Sums of Digits 贪心

这道题目有人用DFS.有人用DP 我觉得还是最简单的贪心解决也是不错的选择. Ok,不废话了,这道题目的意思就是 原先存在一个严格递增的Arrary_A,然后Array_A[i] 的每位之和为Array_B[i] 现在给你一个Array_B, 让你在条件: Array_A[len] Minimize 下求出次数组 (当然我们很容易得出,如果Array_A[len] 不是最小化的,那么答案有无穷多,随意暴力一下都可以) 所以这题没有那么暴力= = 解题思路: 首先求出Array_B[i] 和 Ar

codeforces 509 D. Restoring Numbers(数学+构造)

题目链接:http://codeforces.com/problemset/problem/509/D 题意:题目给出公式w[i][j]= (a[i] + b[j])% k; 给出w,要求是否存在这样的数列,若存在则求出a,b 和k 题解:如果有符合条件的点的话那么a[i],b[j]可以任意转换比如说a[i],b[j]可以转化为a[i]-p,b[i]+p.所以只要存在 符合条件的解的a[i]可以为任意值.也就是说a[i]可以先赋值为0然后其他就都可以推出来了,当然开始推出后会发现 有负的,没事,

【CodeForces 915 C】Permute Digits(思维+模拟)

You are given two positive integer numbers a and b. Permute (change order) of the digits of a to construct maximal number not exceeding b. No number in input and/or output can start with the digit 0. It is allowed to leave a as it is. Input The first

【分块】CODEFORCES 384C Subset Sums

通道 题意:给出n个数,m组序列,然后每次可以选择一个序列给对应的每个数加定值,及询问该组对应数之和 思路:可以知道修改某一组后,肯定对应和其他组有相交部分也要对应修改,每次去修改肯定不现实,然后对于sqrt(n)以内的数可以O(n)修改,其他的只要计算对应的增量即可,然后维护对于大于sqrt(n)的序列会影响到哪些小于sqrt(n)的序列即可. 代码: #include <cstdio> #include <cmath> #include <vector> using

codeforces 1209/C Paint the Digits 观察

题意 给你一个序列 问你能否选出两个序列 然后拼接 是他们成为有序的序列 输出方案 解: 说下我的思路 开始我吧题目看错了以为求的是单调递减的... 这题考的是贪心加观察 后来才发现 然后我又试了lis 树状数组 都不行 最后我发现对于一个序列 最终状态一定是有序的 那么我们不妨对于这个序列首先进行双关键字排序 然后 最小的一个一定是1 然后 我们对于每一个必须为1 的标上1 注意判断重复元素 code: // // main.cpp // sadf // // Created by ALEZ

Codeforces Round #289

A Maximum in Table B Painting Pebbles C Sums of Digits D Restoring Numbers E Pretty Song F Progress Monitoring 总结 1. B题一开始有些马虎,没有读完题就开始做,结果理解错题意WA了一次(样例居然还是一次就过的-).以后要把题目读完再开始做.这种做法虽然在读题上花费的时间多了,但却节省了更多的做题时间,所以我认为这是很有必要的. 题解 A. Maximum in Table i=1 或