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)

/**
 * code generated by RHelper
 * More info: https://github.com/mkc1370/RHelper
 * @author 
 */

using Task.DLunlunNumber;

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace Task.DLunlunNumber
{
    public class DLunlunNumber
    {
        string[] table = new string[((int)1e5)+10];
        private int count = 0;
        public void Solve()
        {
            var k = CINL;

            // if (k < 10)
            // {
            //     COUT(k);
            //     return;
            // }
            //
            // if (k < 100)
            // {
            //     COUT(k);
            //     return;
            // }

            for (var i = 1; ; i++)
            {
                F("1", i);
                F("2", i);
                F("3", i);
                F("4", i);
                F("5", i);
                F("6", i);
                F("7", i);
                F("8", i);
                F("9", i);
                if (count >= k) break;
            }
            COUT(table[k-1]);
        }

        private void F(string s, int len)
        {
            if(count>=(int)1e5) return;
            if (s.Length == len)
            {
                table[count++] = s;
                return;
            }else if (s.Length > len)
            {
                return;
            }

            var last = s.Last();
            if (last == '0')
            {
                F($"{s}0", len);
                if(s.Length > len) return;
                F($"{s}1", len);
                if(s.Length > len) return;
            }
            else if(last <= '8')
            {
                F($"{s}{(char)(last + -1)}", len);
                if(s.Length > len) return;
                F($"{s}{(char)(last + 0)}", len);
                if(s.Length > len) return;
                F($"{s}{(char)(last + 1)}", len);
                if(s.Length > len) return;
            }
            else
            {
                F($"{s}8", len);
                if(s.Length > len) return;
                F($"{s}9", len);
                if(s.Length > len) return;
            }
        }
        
        private readonly StringReader cin;
        private readonly StringWriter cout;
        private readonly Scanner scanner;

        public DLunlunNumber(StringReader cin, StringWriter cout)
        {
            this.cin = cin;
            this.cout = cout;
            scanner = new Scanner(cin);
        }

        private long CINL => scanner.Long();
        private double CIND => scanner.Double();
        private string CINS => scanner.String();
        private static IEnumerable<T> Repeat<T>(T v, long n) => Enumerable.Repeat(v, (int)n);
        private List<long> CINVL(long n) => Repeat(0, n).Select(_ => CINL).ToList();
        private List<double> CINVD(long n) => Repeat(0, n).Select(_ => CIND).ToList();
        private List<string> CINVS(long n) => Repeat(0, n).Select(_ => CINS).ToList();

        private void COUT(object o) => cout.WriteLine(o);
    }


    public class Scanner
    {
        public Scanner(StringReader stringReader)
        {
            this.stringReader = stringReader;
        }

        private readonly StringReader stringReader;
        private readonly char[] buffer = new char[1024];
        private int len, ptr;
        private bool isEof;

        private char Read()
        {
            if (isEof) throw new EndOfStreamException();
            if (ptr >= len)
            {
                ptr = 0;
                if ((len = stringReader.Read(buffer, 0, 1024)) <= 0)
                {
                    isEof = true;
                    return '\0';
                }
            }

            return buffer[ptr++];
        }

        public char Char()
        {
            char b;
            do b = Read();
            while (b < 33 || 126 < b);
            return b;
        }

        public string String()
        {
            var sb = new StringBuilder();
            for (char b = Char(); b >= 33 && b <= 126; b = Read())
                sb.Append(b);
            return sb.ToString();
        }

        public long Long()
        {
            long ret = 0;
            char b;
            var ng = false;
            do b = Read();
            while (b != '-' && (b < '0' || '9' < b));
            if (b == '-')
            {
                ng = true;
                b = Read();
            }

            for (;; b = Read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }

        public double Double()
        {
            return double.Parse(String(), CultureInfo.InvariantCulture);
        }
    }

    public struct ModInt
    {
        public const int Mod = 1000000007;
        private const long Positivizer = ((long)Mod) << 31;
        private long data;
        public ModInt(long data) { if ((this.data = data % Mod) < 0) this.data += Mod; }
        public static implicit operator long(ModInt modInt) => modInt.data;
        public static implicit operator ModInt(long val) => new ModInt(val);
        public static ModInt operator +(ModInt a, int b) => new ModInt() { data = (a.data + b + Positivizer) % Mod };
        public static ModInt operator +(ModInt a, long b) => new ModInt(a.data + b);
        public static ModInt operator +(ModInt a, ModInt b) { long res = a.data + b.data; return new ModInt() { data = res >= Mod ? res - Mod : res }; }
        public static ModInt operator -(ModInt a, int b) => new ModInt() { data = (a.data - b + Positivizer) % Mod };
        public static ModInt operator -(ModInt a, long b) => new ModInt(a.data - b);
        public static ModInt operator -(ModInt a, ModInt b) { long res = a.data - b.data; return new ModInt() { data = res < 0 ? res + Mod : res }; }
        public static ModInt operator *(ModInt a, int b) => new ModInt(a.data * b);
        public static ModInt operator *(ModInt a, long b) => a * new ModInt(b);
        public static ModInt operator *(ModInt a, ModInt b) => new ModInt() { data = a.data * b.data % Mod };
        public static ModInt operator /(ModInt a, ModInt b) => new ModInt() { data = a.data * GetInverse(b) % Mod };
        public static bool operator ==(ModInt a, ModInt b) => a.data == b.data;
        public static bool operator !=(ModInt a, ModInt b) => a.data != b.data;
        public override string ToString() => data.ToString();
        public override bool Equals(object obj) => obj != null && (ModInt)obj == this;
        public override int GetHashCode() => (int)data;

        private static long GetInverse(long a)
        {
            long div, p = Mod, x1 = 1, y1 = 0, x2 = 0, y2 = 1;
            while (true)
            {
                if (p == 1) return x2 + Mod; div = a / p; x1 -= x2 * div; y1 -= y2 * div; a %= p;
                if (a == 1) return x1 + Mod; div = p / a; x2 -= x1 * div; y2 -= y1 * div; p %= a;
            }
        }
    }
}


public class Output
{
	public static void Main()
	{
		var reader = new System.IO.StringReader(Console.In.ReadToEnd());
		var writer = new System.IO.StringWriter();
		var solver = new DLunlunNumber(reader, writer);
		solver.Solve();
		System.Console.Write(writer.GetStringBuilder().ToString());
	}
}