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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
#define null NULL
#define mp make_pair
#define pb(a) push_back(a)
#define sz(a) ((int)(a).size())
#define all(a) a.begin() , a.end()
#define fi first
#define se second
#define relaxMin(a , b) (a) = min((a),(b))
#define relaxMax(a , b) (a) = max((a),(b))
#define SQR(a) ((a)*(a))
#define PI 3.14159265358979323846
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

const int LEN = 16;

ll Rev(ll w){
  vi num;
  while(w > 0) num.pb(w % 10), w /= 10;
  ll res = 0;
  for(int e : num)
    res = 10 * res + e;
  return res;
}

int let[LEN + 10];
bool pm[LEN + 10], ps[LEN + 10];
ll ans = 0;

int save[500][2];

/*
int How(int d, int d0){  // a = b + d
  if(save[d + 250][d0] >= 0)
    return save[d + 250][d0];

  int& res = save[d + 250][d0];
  res = 0;
  for(int a, b = d0 ? 1 : 0;b < 10;++b){
    a = b + d;
    if(a < 0 || a >= 10) continue;
    ++res;
  }
  return res;
}
*/
int How(bool pm_fa, bool ps_fa, int v_fa,
        bool pm_af, bool ps_af, int v_af,
        bool can_0){ // fa
  int res = 0;

  for(int f = 0;f < 10;++f)
    for(int a = 0;a < 10;++a){
      if(!can_0 && f == 0) continue;

      int _a = a, _f = f;
      if(pm_fa) --_f;
      if(ps_fa && _f >= _a) continue;
      if(ps_fa) _f += 10;
      if(_f - _a != v_fa) continue;

      _a = a, _f = f;
      if(pm_af) --_a;
      if(ps_af && _a >= _f) continue;
      if(ps_af) _a += 10;
      if(_a - _f != v_af) continue;

      ++res;
    }

  return res;
}


void Doit(int len){
  //for(int msk = 0;msk < (1 << (2 * len));++msk){
  for(int msk = 0;msk < (1 << (len - 1));++msk){
    for(int i = 0;i < len;++i) pm[i] = ps[i] = false;
    for(int i = 0;i < len - 1;++i)
      if(msk & (1 << i)){
        ps[i] = true;
        pm[i + 1] = true;
      }
    //for(int i = 0;i < len;++i){
    //  pm[i] = (msk & (1 << (2 * i))) ? true : false;
    //  ps[i] = (msk & (1 << (2 * i + 1))) ? true : false;
    //}

    /*
    bool fine = true;
    if(pm[0]) continue;
    if(ps[len - 1]) continue;
    for(int i = 1;i < len;++i)
      if(ps[i - 1] != pm[i]){
        fine = false;
        break;
      }
    if(!fine) continue;
    */

    // Processing
    ll res = 1;
    int mid = len >> 1;
    for(int i = 0;i < mid;++i){
      int c1 = i, c2 = len - 1 - i;
      res *= How(pm[c1], ps[c1], let[c1],
                 pm[c2], ps[c2], let[c2],
                 (c1 == 0) ? false : true);
      /*
      int d1 = 0, x1 = let[c1];
      int d2 = 0, x2 = let[c2];

      if(pm[c1]) --d1;
      if(ps[c1]) d1 += 10;
      if(pm[c2]) --d2;
      if(ps[c2]) d2 += 10;

      d1 = d1 - x1;
      d2 = x2 - d2;
      if(d1 != d2){
        res = 0;
        break;
      }

      if(i == 0) res *= How(d1, true);
      else res *= How(d1, false);
      if(res == 0) break;
      */
    }

    // middle
    if(len & 1){
      int d = 0;
      if(pm[mid]) --d;
      if(ps[mid]) d += 10;
      if(d != let[mid]) res = 0;
      else res *= 10;
    }

    ans += res;
  }
  //}
}

int main(){
  //cout << Rev(1627436254LL) - 1627436254LL << endl;
  memset(save, -1, sizeof save);

  //for(int i = 0;i < 1000000;++i)
  ll d;
  cin >> d;
  //d = 63;
  for(int i = 0;i < LEN;++i)
    let[i] = d % 10, d /= 10;

  //Doit(2);
  for(int len = 1;len <= LEN;++len)
    Doit(len);

  cout << ans << '\n';

  //printf("%.3f\n", (clock() - 0.0) / CLOCKS_PER_SEC);
  return 0;
}