1. 程式人生 > >C. Classy Numbers cf edu round50

C. Classy Numbers cf edu round50

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[20][10];//從低位到高位第i位數字中非零數字小於等於j的數字個數 
ll cal(ll num)
{
    if(num==0)//這裡不特判會出來一堆奇妙的結果 
      return 1;
    vector<ll> vec;
    vec.push_back(0);
    while(num)
    {
        vec.push_back(num%10);
        num/=10;
    }
    int
cnt=0; ll ans=0; for(int i=vec.size()-1;i>1;i--) { if(vec[i]) { if(cnt<3) { ans+= ( (vec[i]-1)*dp[i-1][3-cnt-1]+dp[i-1][3-cnt] ); } else if(cnt==3) { ans += dp[i-1][0]; } cnt
++; } } if(cnt<=2) ans+=vec[1]; if(cnt<=3) ans++; return ans; } int main() { int T; scanf("%d",&T); dp[1][0]=1; dp[1][1]=9; for(int i=2;i<=18;i++) { dp[i][0]=1; for(int j=1;j<=3;j++) { dp[i][j]
=dp[i-1][j-1]*9+dp[i-1][j];//這裡得到的是從低位到高位前i位數字非零數字位j個的時候數字的數量 } } for(int i=1;i<=18;i++) { for(int j=1;j<=3;j++) { dp[i][j]+=dp[i][j-1]; } } while(T--) { ll L,R; scanf("%lld%lld",&L,&R); printf("%lld\n",cal(R)-cal(L-1)); } }