Problem:
Score : 400 points

Problem Statement

A positive integer X is said to be a lunlun number if and only if the following condition is satisfied:

In the base ten representation of X (without leading zeros), for every pair of two adjacent digits, the absolute difference of those digits is at most 1.

For example, 1234, 1, and 334 are lunlun numbers, while none of 31415, 119, or 13579 is.

You are given a positive integer K. Find the K-th smallest lunlun number.

Constraints

1 \leq K \leq 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

K

Output

Print the answer.

Sample Input 1

15

Sample Output 1

23

We will list the 15 smallest lunlun numbers in ascending order:

1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
21,
22,
23.

Thus, the answer is 23.

Sample Input 2

1

Sample Output 2

1

Sample Input 3

13

Sample Output 3

21

Sample Input 4

100000

Sample Output 4

3234566667

Note that the answer may not fit into the 32-bit signed integer type.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AtCoderCs
{
   class Program
   {
       static void Main()
       {

           // Num...問題文における 'K' 
           Num = int.Parse(Console.ReadLine());

           // digit...桁数
           var digit = 0;

           // i...カウンター('i == Num' になった時の
           // 'LunLun' 値が計算結果
           i = 0;

           // 'LunLunGetter(int, int)'内で計算を行う
           // 'i == Num' になった時ループを抜けて終了する
           for (; LunLunGetter(digit, -1); digit++) ;


       }

       static int[] LunLun = new int[0];
       static int Num;
       static int i;
       static bool LunLunGetter(int targetDigit, int previousDigit = -1)
       {
           
           // targetDigit...使用する桁数（というか最大インデックス）
           // 実際に使用する桁数は 'targetDigit + 1'
           // previousDigit...ひとつ前の'LunLunGetter'が計算していた数値のある桁数
           // （というかやっぱり0から始まるインデックス）

           // start, end...このメソッドが計算する桁で取りうる値の最小・最大値
           // nowDigit...このメソッドが計算する桁（というかインデックス）

           int start, end;
           var nowDigit = previousDigit + 1;

           // 一桁目（インデックス的には0）から計算する場合
           if (nowDigit == 0)
           {

               // LunLunを初期化しなくちゃいけないから初期化
               LunLun = new int[targetDigit + 1];

               // 一桁目は0以外何でもよいから1以上10未満
               start = 1; end = 10;

           }
           else
           {

               // それ以外は前の桁の数値に依存するからここでswitch
               switch (LunLun[previousDigit])
               {
               case 0:

                   // 0以上2未満
                   start = 0; end = 2;
                   break;
               
               case 9:

                   // 8以上10未満
                   start = 8; end = 10;
                   break;

               default:

                   // その数より1小さい奴以上2大きい奴未満
                   start = LunLun[previousDigit] - 1;
                   end = LunLun[previousDigit] + 2;
                   break;
               }
           }

           // 検証
           for (LunLun[nowDigit] = start; LunLun[nowDigit] < end; LunLun[nowDigit]++)
           {

               // 目的の桁数に達していない場合
               if (targetDigit != nowDigit)
               {

                   // 次の桁を調べる 'LunLunGetter' を呼び出し、その中で値が出力完了した場合は終了する
                   if (!LunLunGetter(targetDigit, nowDigit)) return false;                   
               }
               else
               {

                   // 目的の桁に達した場合
                   // ルンルン数として数える
                   i++;

                   // ルンルン数取得が終了した場合
                   if (i == Num)
                   {

                       LunLun.ToList().ForEach(x => Console.Write(x));
                       return false;

                   }

               }

           }

           return true;

       }

   }
}