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 PHP7 (7.0.15) (judge verdict: Wrong Answer)

<?php
$n = trim(fgets(STDIN));
$k = (int)trim(fgets(STDIN));

$exp = strlen((string)$n) - 1;

$sum = 0;
switch ($k) {
	case 1:
		for ($i=0; $i <= $exp; $i++) { 
			for ($inum=1; $inum <= 9; $inum++) { 
				$num = $inum * pow(10, $i);
				if ($num <= $n) {
					$sum += 1;
				}
			}
		}
		break;
	case 2:
		for ($i=0; $i <= $exp-1; $i++) { 
			$num = 0;
			for ($inum=1; $inum <= 9; $inum++) { 
				if ($inum * pow(10, $i) >= $n) {
					break;
				}
				if ($i === $exp) {
					for ($j=$i+1; $j <= $exp; $j++) { 
						for ($jnum=1; $jnum <= 9; $jnum++) {
							$num = $inum * pow(10, $i) + $jnum * pow(10, $j);
							if ($num <= $n) {
								$sum += 1;
							}
						}
					}
				}else{
					$sum += ModComb::singleComb($i, 1, 1000000007) * 9;
				}
			}
		}
		break;
	case 3:
		for ($i=$exp; $i >= 2; $i--) { 
			$num = 0;
			for ($inum=1; $inum <= 9; $inum++) { 
				if ($inum * pow(10, $i) >= $n) {
					break;
				}
				if ($i === $exp) {
					for ($j=$i-1; $j >= 1; $j--) { 
						for ($jnum=1; $jnum <= 9; $jnum++) {
							if ($inum * pow(10, $i) + $jnum * pow(10, $j) >= $n) {
								break;
							}
							for ($k=$j-1; $k >= 0; $k--) { 
								for ($knum=1; $knum <= 9; $knum++) {
									$num = $inum * pow(10, $i) + $jnum * pow(10, $j) + $knum * pow(10, $k);
									if ($num > $n) {
										break;
									}
									$sum += 1;
								}
							}
						}
					}
				}else{
					$sum += ModComb::singleComb($i, 2, 1000000007) * 81;
				}
			}
		}
		break;
}

echo $sum;


class ModComb
{
	// 事前計算テーブル
	private $f_table  = [1]; // $n! % $mod
	private $if_table = [1]; // $k!の($mod-2)乗 % $mod
	// 十分大きな素数にする
	private $mod = 0;

	public function __construct($max = 10000, $mod = 1000000007){
		$this->mod = $mod;
		// 事前計算
		$this->calcFactorial($max);
	}

	// 組み合わせ計算（nCm）
	public function comb($n, $m){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < $m || $n < 0) {
			return 0;
		}
		if (!isset($this->f_table[$n])) {
			$this->calcFactorial($n);
		}
		return ($this->if_table[$n - $m] * $this->if_table[$m] % $this->mod) * $this->f_table[$n] % $this->mod;
	}

	// logNで組み合わせを算出する。繰り返し多数の計算が不要な場合にはこちらの方が高速
	public static function singleComb($n, $m, $mod){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < $m || $n < 0) {
			return 0;
		}
		$f_n    = self::singleFact($n, $mod);
		$if_n_m = self::sigleBinPow(self::singleFact($n-$m, $mod), $mod-2, $mod) % $mod;
		$if_m   = self::sigleBinPow(self::singleFact($m, $mod), $mod-2, $mod) % $mod;
		return ($if_n_m * $if_m % $mod) * $f_n % $mod;
	}

	private static function singleFact($n, $mod){
		if ($n < 2) {
			return 1;
		}
		$table = [];
		for ($i=0; $i < $n; $i++) { 
			$table[$i] = $i+1;
		}
		$idx = 1;
		while ($idx <= $n) {
			$span = $idx<<1;
			for ($i=0; $i < $n; $i+=$span) { 
				if ($idx + $i < $n) {
					$table[$i] = ($table[$i] * $table[$i+$idx]) % $mod;
				}
			}
			$idx = $idx<<1;
		}
		return $table[0];
	}

	private static function sigleBinPow($x, $n, $mod){
		$ans = 1;
		$bin = decbin($n);
		$cur_pos = strlen($bin) -1;
		while ($cur_pos >= 0) {
			if ($bin[$cur_pos] == '1') {
				$ans = ($ans * $x) % $mod;
			}
			$x = ($x * $x) % $mod;
			--$cur_pos;
		}
		return $ans;
	}

	// 順列計算（nPm）
	public function perm($n, $m){
		if ($n < $m) {
			return 0;
		}
		if (!isset($this->f_table[$n])) {
			$this->calcFactorial($n);
		}
		return ($this->if_table[$n - $m] % $this->mod) * $this->f_table[$n] % $this->mod;
	}

	// 重複組合せ計算（nHm）
	public function dupc($n, $m){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < 0 || $m === 0) {
			return 0;
		}
		if (!isset($this->f_table[$n + $m - 1])) {
			$this->calcFactorial($n + $m - 1);
		}
		return ($this->if_table[$n - 1] * $this->if_table[$m] % $this->mod) * $this->f_table[$n + $m - 1] % $this->mod;
	}

	// 既存の事前計算結果テーブルの末尾から$maxまでの階乗までtableを拡張する。
	private function calcFactorial($max){
		$already = count($this->f_table);
		for($i = $already; $i <= $max; $i++){
			$this->f_table[$i] = $this->f_table[$i-1] * $i % $this->mod;
			$this->if_table[$i] = $this->if_table[$i-1] * $this->binPow($i, $this->mod-2) % $this->mod;
		}
	}

	// $xの$n乗を2進数で高速に計算する
	// これを単体で利用する場合、コンストラクタの$maxは低めで良い
	public function binPow($x, $n){
		$ans = 1;
		$bin = decbin($n);
		$cur_pos = strlen($bin) -1;
		while ($cur_pos >= 0) {
			if ($bin[$cur_pos] == '1') {
				$ans = ($ans * $x) % $this->mod;
			}
			$x = ($x * $x) % $this->mod;
			--$cur_pos;
		}
		return $ans;
	}
}