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: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoders {
	class Program {
		static void Main(string[] args) {
			var inputArray = retreiveLongArray();
			var inputCount = 1;

			// 不正な入力は処理しない
			if (inputArray.Length != inputCount) {
				Console.WriteLine("invalid input");
				return;
			}
			var K = inputArray[0];
			var lunlunTable = new long[12][];

			//一番最初の桁に注目する。Array1は1桁めで、最初の桁が0~9のときのLunLunの数
			lunlunTable[0] = new long[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

			for (int i = 1; i < 12; i++) {
				lunlunTable[i] = getNextLunlunArray(lunlunTable[i - 1]);
			}

			var ketaInitial = getKeta_Initial(lunlunTable, K);

			var keta = ketaInitial.keta;
			var remain = ketaInitial.remain;
			var ans = ketaInitial.initial.ToString();
			var ini = ketaInitial.initial;

			while (keta > 0) {
				if(ini>0 & remain <= lunlunTable[keta - 1][ini-1]) {
					ans = ans + (ini - 1);
				}
				else if (remain <= lunlunTable[keta - 1][ini - 1]+ lunlunTable[keta - 1][ini]) {
					ans = ans + (ini);
					remain = -lunlunTable[keta - 1][ini - 1];
				}
				else {
					ans = ans + (ini+1);
					remain = -lunlunTable[keta - 1][ini - 1]+ lunlunTable[keta - 1][ini];
				}
				keta--;
			}
			Console.WriteLine(ans);

		}

		/// <summary>
		/// スペースで区切られた文字列配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static KetaInital getKeta_Initial(long[][] lunlunTable, long K) {

			long remain = K;

			for (int keta = 0; keta < 12; keta++) {
				for (int initial = 1; initial <= 9; initial++) {
					if (remain <= lunlunTable[keta][initial]) {

						//if (initial == 1) {
							//return new KetaInital(keta - 1, 9, remain);
						//}//
						return new KetaInital(keta, initial , remain);
					}
					remain = remain - lunlunTable[keta][initial];

				}
			}
			//このコードは通らない想定
			return new KetaInital(-1, -1,1);

		}


		/// <summary>
		/// スペースで区切られた文字列配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static long[] getNextLunlunArray(long[] lunlunArray) {
			var nextLunlunArray = new long[10];

			for (int i = 0; i < 10; i++) {
				long value = 0;

				if (i - 1 >= 0) {
					value += lunlunArray[i - 1];
				}
				value += lunlunArray[i];

				if (i + 1 < 10) {
					value += lunlunArray[i + 1];
				}

				nextLunlunArray[i] = value;
			}

			return nextLunlunArray;
		}



		/// <summary>
		/// スペースで区切られた文字列配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static string[] retreiveStringArray() {
			var inputArray = Console.ReadLine().Split(' ');
			return inputArray;
		}

		/// <summary>
		/// スペースで区切られた整数配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static long[] retreiveLongArray() {
			var inputArray = Console.ReadLine().Split(' ');
			var longArray = inputArray.Select(s => long.Parse(s));
			return longArray.ToArray();
		}
	}

	public class KetaInital {
		public int keta { get; set; }
		public int initial { get; set; }
		public long remain { get; set; }


		public KetaInital(int k,int i,long r) {
			keta = k;
			initial = i;
			remain = r;
		}
	}
}