Я решил написать небольшой кусочек кода, который получит два целых числа, скажем, M и N (M <= N) и суммировать цифры всех целых чисел между ними включительно. Так, например, если M = 1 и N = 9, DigitSum будет равен 45. Если M = 10 и N = 11, сумма будет (1 + 0 (10) + 1 + 1 (11) = 3).
Вот мой код (закончил цикл for вместо возврата):
#include <iostream>
#include <vector>
using namespace std;
// the partial digits sums digitSum[i] = the sum of the digits between 0 and i
int digitSum[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45};
int pow_of_ten[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
// the sums of all the digits in the numbers from 1 to (10^(i) - 1) where i is the index in the array
long subsums[] = {0, 45, 20 * 45, 300 * 45, 4000 * 45, 50000 * 45, 600000 * 45, 7000000 * 45, 80000000 * 45,
900000000 * 45};
//Calculates the sum of all digits between 0 and M inclusive
long Digit_Sum(int M) {
if (M < 10) {
return digitSum[M];
}
long result = 0;
int same = M;
int counter = 0;
int lastdigit = 0;
while (same > 0) {
if (same < 10) {
lastdigit = same;
break;
}
same /= 10;
counter ++;
}
for(;counter >= 0; counter --) {
result += (subsums[counter] + M % pow_of_ten[counter] + 1) * lastdigit;
result += digitSum[lastdigit - 1] * pow_of_ten[counter];
if (counter == 0) {
break;
}
lastdigit = (M / pow_of_ten[counter - 1]) % 10;
}
return result;
}
int main() {
int M;
int N;
vector<long> sums;
while (true) {
cin >> M >> N;
if (M == 0 && N == 0) {
break;
}
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
}
for (vector<long>::iterator it = sums.begin(); it != sums.end(); ++it) {
cout << *it << endl;
}
}
В большинстве случаев это работает хорошо, но онлайн-судья говорит, что это неправильно. Я посмотрел на другие решения, которые работают, но никто не жестко закодировал значения в массивах так, как я. Может ли это вызвать частичную проблему, есть идеи?
Вы можете легко создать цикл for, чтобы значительно упростить этот код.
Нет необходимости проходить через все эти усилия.
for (Initialization Action, Boolean Expression, Update_Action)
Повторное удаление ниже: извините, у меня есть немного гриппа и Mizread N
как M
, 🙁
Я думаю, что главная ошибка M-1
в
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
Также отмечая, что <когда исправлено эта формула будет работать только для однозначных чисел. Мой комментарий ранее об использовании простой формулы был основан на неправильном понимании описания вашей проблемы ввиду этой формулы и ваших примеров. Оба указали только однозначные числа.
Однако сложность кода кажется неоправданно высокой. Рассмотрим это, принимая неотрицательные целые числа в качестве входных данных, и предполагая, m
всегда меньше или равно n
:
#include <iostream>
#include <stdexcept>
using namespace std;
bool throwX() { throw std::runtime_error( "Ouch." ); }
auto main() -> int
{
for( ;; )
{
int m, n;
cin >> m >> n || throwX();
if( m == 0 && n == 0 ) { break; }
int sum = 0;
for( int i = m; i <= n; ++i )
{
for( int v = i; v != 0; v /= 10 )
{
sum += v % 10;
}
}
cout << sum << endl;
}
}
Это не должно быть сложнее, чем это.
Протестировано и работает по спецификации, без ввода с консоли:
#include <iostream>
#include <string>
using namespace std;
void sum_a_to_b(const int & a, const int & b)
{
if (a <= b && a >= 0)
{
long long sum = 0;
for (int i = a; i <= b; i++)
{
sum += i;
}
cout << "Sum of digits from " << a << " through " << b << " is " << sum << ".\n";
}
}
int main()
{
sum_a_to_b(5, 6);
sum_a_to_b(1, 9);
}