Editorial for COCI '13 Contest 3 #5 Parovi


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Since this is all about big numbers, obviously calculating the distance for each pair individually is not fast enough. Nevertheless, we'll do it in a very specific way.

We won't go through all numbers with two nested loops, but create a function f(prefix1, prefix2, sum) which will build the numbers digit by digit.

For example, a pair of numbers (32, 1689) would be built by adding digits, respectively, (0, 1), (0, 6), (3, 8), (2, 9).

Function f would look like this:

f(prefix1, prefix2, sum):
  if prefixes are completely built, return sum

  let (x, y) go through all possible pairs of digits:
    if you can add x on prefix1 and y on prefix2:
      call f(prefix1 * 10 + x, prefix2 * 10 + y, sum + |x - y|)

This solution is not quicker than the two nested loops solution, but it can be tweaked. First we will get rid of the sum parameter from the function.

We will build a function num(prefix1, prefix2) which, for given prefixes of the first and second number, calculates the number of ways to "finish" these two numbers.

num(prefix1, prefix2):
  if prefixes are completely built, return 1

  sol = 0
  let (x, y) go through all possible pairs of digits:
    if you can add x on prefix1 and y on prefix2:
      sol = sol + num(prefix1 * 10 + x, prefix2 * 10 + y)
  return sol

Now the function f can be transformed as follows:

f(prefix1, prefix2):
  if prefixes are completely built, return 0

  sol = 0
  let (x, y) go through all possible pairs of digits:
    if you can add x on prefix1 and y on prefix2:
      sol = sol + num(prefix1 * 10 + x, prefix2 * 10 + y) * |x - y|
      sol = sol + f(prefix1 * 10 + x, prefix2 * 10 + y)
  return sol

The only thing left to notice is that we do not need to know the whole prefix in order to know whether we can add digit x. It is sufficient to know how many times we have added a digit before this one and whether the prefix has ever been different than the upper and lower interval bounds. This gives us a dynamic programming approach with \mathcal O(\text{number_length} * \text{number_of_possible_digits}^2) complexity.


Comments

There are no comments at the moment.