Problem:
Score : 500 points

Problem Statement

Find the number of integers between 1 and N (inclusive) that contains exactly K non-zero digits when written in base ten.

Constraints

1 \leq N < 10^{100}

1 \leq K \leq 3

Input

Input is given from Standard Input in the following format:

N
K

Output

Print the count.

Sample Input 1

100
1

Sample Output 1

19

The following 19 integers satisfy the condition:

1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100

Sample Input 2

25
2

Sample Output 2

14

The following 14 integers satisfy the condition:

11,12,13,14,15,16,17,18,19,21,22,23,24,25

Sample Input 3

314159
2

Sample Output 3

937

Sample Input 4

9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
3

Sample Output 4

117879300

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using static System.Console;
using static System.Math;
using static MyIO;
using static MyUtil;

public class E
{
	public static void Main() => (new Solver()).Solve();
}

public class Solver
{
	public void Solve()
	{
		string N = GetString();
		int K = GetInt();
		
		int L = N.Length;
		int[] num = new int[L];
		for(int i = 0; i < L; i++)
			num[i] = (int)(N[i] - '0');

		long[,,] dp = new long[L, L - K + 1, 2];
		if(L - K > 0)
			dp[0, 1, 1] = 1;

		for(int i = 1; i < num[0]; i++)
			dp[0, 0, 1]++;

		dp[0, 0, 0] = 1;
		for(int i = 1; i < L; i++)
		{
			for(int j = 0; j <= L - K; j++)
			{
				if(j < L - K)
				{
					if(num[i] == 0)
					{
						dp[i, j + 1, 0] += dp[i - 1, j, 0];
						dp[i, j + 1, 1] += dp[i - 1, j, 1];
					}
					else
					{
						dp[i, j + 1, 1] += dp[i - 1, j, 0] + dp[i - 1, j, 1];
					}
				}

				for(int l = 1; l < 10; l++)
				{
					if(l < num[i])
					{
						dp[i, j, 1] += dp[i - 1, j, 0] + dp[i - 1, j, 1];
					}
					else if(l == num[i])
					{
						dp[i, j, 0] += dp[i - 1, j, 0];
						dp[i, j, 1] += dp[i - 1, j, 1];
					}
					else
					{
						dp[i, j, 1] += dp[i - 1, j, 1];						
					}
				}
			}
		}

		WriteLine(dp[L - 1, L - K, 0] + dp[L - 1, L - K, 1]);
	}
}

public static class MyIO
{
	private static string[] args = null;
	private static int num = -1;
	private static int used = -1;

	private static string getArg()
	{
		if(used == num)
		{
			args = Console.ReadLine().Split(' ');
			num = args.Length;
			used = 0;
		}
		return args[used++];
	}

	public static int GetInt() => int.Parse(getArg());
	public static long GetLong() => long.Parse(getArg());
	public static double GetDouble() => double.Parse(getArg());
	public static decimal GetDecimal() => decimal.Parse(getArg());
	public static string GetString() => getArg();
	public static char GetChar() => getArg()[0];
	public static int[] GetInts(long N) => Enumerable.Range(0, (int)N).Select(_ => GetInt()).ToArray();
	public static long[] GetLongs(long N) => Enumerable.Range(0, (int)N).Select(_ => GetLong()).ToArray();
	public static double[] GetDoubles(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDouble()).ToArray();
	public static decimal[] GetDecimals(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDecimal()).ToArray();
	public static string[] GetStrings(long N) => Enumerable.Range(0, (int)N).Select(_ => GetString()).ToArray();
}

public static class MyUtil
{
	public static void chmax<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) < 0)
			x = y;
	}

	public static void chmin<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) > 0)
			x = y;
	}

	public static void swap<T>(ref T x, ref T y)
	{
		T tmp = x;
		x = y;
		y = tmp;
	}
}