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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)


#include "bits/stdc++.h"
#include <unordered_set>
#define rep(i,n) for(ll i = 0; i < n; i++)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
#define vll vector<vector<long long>>
#define vl vector<long long>
#define vi vector<int>
#define vii vector<vector<int>>
#define pb push_back
#define pf push_front
#define ld long double
#define Sort(a) sort(a.begin(),a.end())
#define cSort(a,cmp) sort(a.begin(),a.end(),cmp)
#define reSort(a) sort(a.rbegin(), a.rend())
static const ll llMAX = numeric_limits<long long>::max();
static const int intMAX = numeric_limits<int>::max();
static const ll  llMIN = numeric_limits<long long>::min();
static const int intMIN = numeric_limits<int>::min();
static const ll d_5 = 100000;
static const ll d9_7 = 1000000007;
static const ll d_9 = 1000000000;
static const double PI=3.14159265358979323846;
//<<std::setprecision(30)
template<class T>
void Printvector(std::vector<T> a){
  int size = a.size();
  rep(i,size){
    cout<<a[i]<<" ";
  }
  cout<<endl;
}
template<class T>
void Printvector(std::vector<std::vector<T>> a){
  int size = a.size();
  rep(i,size){
    int size2=a[i].size();
    rep(j,size2){
      cout<<a[i][j]<<" ";
    }
    cout<<endl;
  }
  cout<<endl;
}
ll digitpower(ll a,ll b){//aのb乗を計算
  if(b==1){
    return a;
  }else if(b==0){
    return 1;
  }
  if(b%2==1){
    ll tmp = digitpower(a,(b-1)/2);
    tmp%=d9_7;
    tmp*=tmp;
    tmp%=d9_7;
    tmp*=a;
    return (tmp)%d9_7;
  }else{
    ll tmp = digitpower(a,(b)/2);
    tmp%=d9_7;
    tmp*=tmp;
    tmp%=d9_7;
    return (tmp)%d9_7;
  }
}

unordered_map<ll,ll> prime_factor(int64_t n) {
  unordered_map<ll,ll> ret;
  for(int64_t i = 2; i * i <= n; i++) {
    while(n % i == 0) {
      ret[i]++;
      n /= i;
    }
  }
  if(n != 1) ret[n] = 1;
  return ret;
}
/*struct datas{
  int num;
  int index;
};
bool cmp(const datas &a, const datas &b)
{
    return a.num < b.num;
}*/
template<class T>
vector<T> getaccum(vector<T> a){
  int size=a.size();
  vector<T> ans(size);
  ans[0]=a[0];
  for(int i=0;i<size-1;i++){
    ans[i+1]=ans[i]+a[i+1];
    ans[i+1]%=d9_7;
  }
  return ans;
}


int main(void){
  int k;
  string n;
  cin>>n>>k;
  int size=n.size();
  if(k==1){
    int ans=0;
    int past=0;
    for(int i=0;i<size;i++){
      //cout<<ans<<endl;
      if(past==1){
        ans+=9;//この桁はどんな数字でも選択できる
        continue;
      }
      ans+=n[i]-'0';
      if(n[i]-'0'>=1){
        past=1;
        //cout<<past<<endl;
      }
    }
    cout<<ans<<endl;
    return 0;
  }
  vl nums1(size,0);//1つ、選ぶパターンを各桁について
  for(ll i=size-1;i>=0;i--){
    if(i==size-1){//最も右,right
      nums1[i]=n[i]-'0';
    }else{
      nums1[i]=n[i]-'0'+nums1[i+1];
    }
  }
  //Printvector(nums1);
  vl nums2(size,0);
  for(ll i=size-1;i>=0;i--){
    if(i==size-1){//最も右,right
      nums2[i]=0;//1中から2つはえらべない
    }else{
      nums2[i]=0;
      //つぎに、ここが1以降
      if(n[i]-'0'==1){
        nums2[i]+=max(((((size-1)-i)*((size-1)-i-1))/2)*9*9,(ll)0);//0の時、2つえらぶ
        nums2[i]+=nums1[i+1];//1のとき
      }else if(n[i]-'0'>=2){
        //2以降
        nums2[i]+=nums1[i+1];//まず、ここがn[i]、つまり最大にした時のパターン
        nums2[i]+=max(((((size-1)-i)*((size-1)-i-1))/2)*9*9,(ll)0);//0
        nums2[i]+=max((ll)0,(n[i]-'0'-1)*((size-1)-i)*9);
      }else if(n[i]-'0'==0){
        nums2[i]=nums2[i+1];
      }
    }
  }
  //Printvector(nums2);
  vl nums3(size,0);
  for(ll i=size-1;i>=0;i--){
    if(i==size-1 || i==size-1-1){//最も右,right
      nums3[i]=0;
    }else{
      nums3[i]=0;
      //つぎに、ここが1以降
      ll tmp=max(((((size-1)-i)*((size-1)-i-1)*(size-1-i-2))/6)*9*9,(ll)0);
      if(n[i]-'0'==1){
        nums3[i]+=tmp;//0の時、3つえらぶ
        nums3[i]+=nums2[i+1];//1のとき
      }else if(n[i]-'0'>=2){
        //2以降
        nums3[i]+=nums2[i+1];//まず、ここがn[i]、つまり最大にした時のパターン
        nums3[i]+=tmp;//0
        nums3[i]+=max((ll)0,(n[i]-'0'-1)*((((size-1)-i)*((size-1)-i-1))/2)*9*9);//1からn[i]-1まで
      }else if(n[i]-'0'==0){
        nums3[i]=nums3[i+1];
      }
    }
  }
  
  Printvector(nums3);
  if(k==2){
    cout<<nums2[0]<<endl;
  }else if(k==3){
    cout<<nums3[0]<<endl;
  }
  return 0;
}