Problem:
Score : 800 points

Problem Statement

For a positive integer n, we denote the integer obtained by reversing the decimal notation of n (without leading zeroes) by rev(n). For example, rev(123) = 321 and rev(4000) = 4.

You are given a positive integer D. How many positive integers N satisfy rev(N) = N + D?

Constraints

D is an integer.

1 ≤ D < 10^9

Input

Input is given from Standard Input in the following format:

D

Output

Print the number of the positive integers N such that rev(N) = N + D.

Sample Input 1

63

Sample Output 1

2

There are two positive integers N such that rev(N) = N + 63: N = 18 and 29.

Sample Input 2

75

Sample Output 2

0

There are no positive integers N such that rev(N) = N + 75.

Sample Input 3

864197532

Sample Output 3

1920

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;

public static class P
{
    public static void Main()
    {
        var pow10 = new long[10];
        pow10[0] = 1;
        for (int i = 1; i < pow10.Length; i++)
            pow10[i] = pow10[i - 1] * 10;

        var dstr = Console.ReadLine();
        var dLen = dstr.Length;
        var halfLength = dLen / 2;

        long res = 0;
        var d = int.Parse(dstr);
        for (int i = 0; i < pow10[halfLength]; i++)
        {
            var digs = i.ToString().PadLeft(halfLength, '0').Select(x => x - '0').ToArray();
            for (int j = 0; j < (1 << (digs.Length - 1)); j++)
            {
                long curDiff = 0;
                for (int k = 0; k < digs.Length; k++)
                {
                    if ((j >> k & 1) == 1)
                    {
                        //上の桁から引き、下の桁に足す
                        curDiff -= pow10[dLen - k - 1] * digs[k];
                        curDiff += pow10[k] * digs[k];
                    }
                    else
                    {
                        //0の桁は重複カウントがありうるので1に固定(1は最上位に0持ってこれない制約も意味している)
                        if (digs[k] == 0) goto end;
                        //上の桁に足し、下の桁から引く
                        curDiff += pow10[dLen - k - 1] * digs[k];
                        curDiff -= pow10[k] * digs[k];
                    }
                }
                //最上位の桁は0になり得ないため、上の桁に足す(=下の桁の方が大きい場合)で、最上位の場合は0が消える
                if (d == curDiff)
                    res += digs
                        .Select((elem, ind) => ((j >> ind & 1) == 0 && ind == 0 ? 0 : 1) + 9 - elem)
                        .Aggregate(1L, (x, y) => x * y);
                end:;
            }
        }

        //真ん中の桁のぶん
        if (dLen % 2 == 1) res *= 10;
        Console.WriteLine(res);
    }
}