Задача.
На днях первоклассник Вася научился складывать числа. Ему этот процесс очень нравится, и он складывает всё подряд. Когда все числа вокруг оказываются сложенными, Вася обращается к своему старшему брату Пете за новыми числами. После нескольких обращений устав работать генератором случайных чисел, Петя придумал для Васи занятие, которое может надолго того занять.
Он предложил Васе находить суммы цифр последовательных чисел — 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 — и так далее, пока Васе не надоест. Вася оказался в восторге от идеи и принялся за работу. За вчерашний день Вася нашёл суммы цифр каждого из чисел от 1 до 115. Посмотрев на результаты младшего брата, Петя заметил, что суммы цифр последовательных чисел не являются случайными, часто они идут подряд, но полностью закономерность он так и не понял.
Чтобы найти закономерности, Петя решил исследовать крайние случаи, например, какое из чисел даёт максимальную сумму цифр. Данных для чисел до 115 оказалось недостаточно для окончательных выводов, и Пете пришла в голову идея для ускорения вычислений использовать вместо братика компьютер. Поскольку сам он в программировании не очень силён, он обратился за решением этой задачи к Вам.
.
Входные данные
В первой строке входных данных находится число N (1 <= N <= 2 147 483 647).
Выходные данные
Выведите число от 1 до N включительно с максимальной суммой цифр. Если чисел с максимальной суммой цифр несколько, выведите наибольшее из них.
Тесты:
число N |
результат |
1 |
1 |
98 |
98 |
13759 |
9999 |
999756 |
998999 |
2147483647 |
1999999999 |
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
#include <iostream> using namespace std; int TheNumberOfDigits(int n)//Количество цифр в числе { int i=1; while ((n/=10)>0) { i++; } return i; } int sc(int a) //Сумма цифр числа { int sum = 0; while (a/1>0) { sum+=a%10; a/=10; } return sum; } int main() { int n, v, t, x; cin>>n; unsigned long long int a=10; t=TheNumberOfDigits(n); x=n; for (int i=1;i<t;i++) { unsigned long long int b = a*10; v=(n/b)*b+(n%b/a-1)*a+a-1; if (sc(v)>sc(x)) x=v; a*=10; } cout<<x<<endl; return 0; } |
Решение.
Идея данного решения задачи заключается в том, что мы получаем число с большей суммой цифр, но меньше данного, заменяя часть цифр справа на девятки, а первую цифру слева от девяток уменьшаем на единицу. Так мы движемся по разрядам от единиц к десяткам, сотням и т.д., каждый раз сравнивая сумму цифр полученного числа с максимальной суммой цифр, которая у нас была до этого.
Сумму цифр и их количество в числе считают две простых в написании функции, степени (i-я и i+1-я)десятки считаются непосредственно в основном цикле.
Задача взята с сайта e-olymp.com
Ссылка на условие задачи
Ссылка на код на ideone
Ссылка на засчитанное решение
примечание: ссылка на код может выдавать старый вариант кода, где [latex]a[/latex] и [latex]b[/latex] считаются отдельно, а не [latex]b[/latex] выражается через [latex]a[/latex], как в этом коде, в связи с техническими проблемами на ideone. Этот вариант тоже проходит все тесты, однако является несколько менее эффективным.