Редакция для Подсчёт по сумме цифр
Submitting an official solution before solving the problem yourself is a bannable offence.
Автор:
1. Идея
Нужно перебрать все числа от 1 до n, для каждого посчитать сумму его цифр и проверить, равна ли она s.
Если равна — увеличиваем ответ.
Такой подход подходит по ограничениям: n <= 10^6, а сумма цифр одного числа считается очень быстро.
2. Наблюдения
- Сумма цифр числа считается независимо от других чисел.
- Чтобы найти сумму цифр числа, можно:
- брать последнюю цифру через
x % 10, - добавлять её к сумме,
- убирать последнюю цифру через
x //= 10илиx /= 10.
- брать последнюю цифру через
- Так как
nне больше миллиона, у каждого числа не больше 7 цифр. Значит, проверка одного числа занимает совсем немного операций. - Максимальная возможная сумма цифр при таких ограничениях невелика, но в этой задаче это не даёт более простого решения в рамках предложенного эталона — всё равно достаточно обычного перебора.
Например, для числа 203:
203 % 10 = 3, сумма320 % 10 = 0, сумма32 % 10 = 2, сумма5
Значит, сумма цифр числа 203 равна 5.
3. Алгоритм
- Считываем
nиs. - Заводим переменную
ans = 0. - Для каждого числа
iот1доn:- считаем сумму его цифр;
- если она равна
s, увеличиваемans.
- Выводим
ans.
4. Почему это работает
Мы рассматриваем все числа от 1 до n без пропусков.
Для каждого числа алгоритм точно вычисляет сумму его цифр:
- последовательно берёт все цифры справа налево,
- складывает их,
- после удаления всех цифр получает полную сумму цифр числа.
После этого:
- если сумма цифр равна
s, число должно быть учтено в ответе; - если не равна, число не должно быть учтено.
Так как каждое число проверяется ровно один раз, а подходящих чисел мы прибавляем ровно по одному, итоговое значение ans и есть количество чисел от 1 до n с суммой цифр s.
5. Сложность
Пусть у числа не более k цифр. Тогда сумма цифр одного числа считается за O(k).
Мы проверяем n чисел, поэтому общая сложность:
O(n * k)
Так как n <= 10^6, а k мало, этого достаточно.
Память:
O(1), потому что используются только несколько переменных.
6. Код на C++17
#include <iostream>
using namespace std;
int digit_sum(int x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
int main() {
int n, s;
cin >> n >> s;
int ans = 0;
for (int i = 1; i <= n; i++) {
if (digit_sum(i) == s) {
ans++;
}
}
cout << ans << '\n';
return 0;
}
7. Код на Python 3
n, s = map(int, input().split())
ans = 0
for i in range(1, n + 1):
x = i
digit_sum = 0
while x > 0:
digit_sum += x % 10
x //= 10
if digit_sum == s:
ans += 1
print(ans)
Комментарии