Sicily 7969. Digit Sum

7969. Digit Sum

Constraints

Time Limit: 1 secs, Memory Limit: 256 MB

Description

For a pair of integers a and b, the digit sum of the interval [a, b] is defined as the sum of all digits occurring in all numbers between (and including) a and b. For example, the digit sum of [28, 31] can be calculated as:
2+8 + 2+9 + 3+0 + 3+1 = 28
Given the numbers a and b, calculate the digit sum of [a, b].

Input

On the first line one positive number: the number of test cases, at most 100. After that per test
case:

  • one line with two space-separated integers, a and b (0 <= a <= b <= 1015).

Output

Per test case:

  • one line with an integer: the digit sum of [a, b].

Sample Input

3
0 10
28 31
1234 56789

Sample Output

46
28
1128600

Problem Source

2013年每周一赛第五场暨校赛模拟赛III/BAPC 2012

// Problem#: 7969
// Submission#: 3593648
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
// Solution to Digit Sum
// Author: Thomas Beuman

// Time complexity: O(log b)
// Memory: O(1)

// @EXPECTED_RESULTS@: CORRECT

/*
Solution outline:

Compute the digitsum from 0 to b and from 0 to a-1, and subtract the two

Determine the digitsum from 0 to n-1 recursively:
Example:
digitsum(125) = digitsum(120) + sumofdigits(120) + sumofdigits(121) + ... + sumofdigits(124)
  digitsum(120) = 10 * digitsum(12) + (0+1+2+3+4+5+6+7+8+9) * 12
  sumofdigits(120) + sumofdigits(121) + ... + sumofdigits(124) = 5 * sumofdigits(12) + (0+1+2+3+4)
*/

#include <cstdio>
using namespace std;

typedef long long i64;

// Returns the sum of the digits of n
i64 sumofdigits (i64 n)
{ return n ? n%10 + sumofdigits(n/10) : 0;
}

// Returns the sum of all digits from 0 to n-1
i64 digitsum (i64 n)
{ return n < 10 ? n*(n-1)/2
                : digitsum(n%10) + 45 * (n/10) // Last digit
                  + (n%10) * sumofdigits(n/10) + 10 * digitsum(n/10); // Other digits
}

int main()
{ int cases, casenr;
  i64 a, b;
  scanf("%d", &cases);
  for (casenr = 1; casenr <= cases; casenr++)
  { scanf("%lld %lld", &a, &b);
    printf("%lld\n", digitsum(b+1) - digitsum(a));
  }
  return 0;
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值