ACdream 完美数 数位DP

  题目链接:http://www.acdream.net/problem.php?id=1083

  简单数位DP,貌似我写得太暴力了= =

  1 //STATUS:C++_AC_20MS_1512KB

  2 #include<stdio.h>

  3 #include<stdlib.h>

  4 #include<string.h>

  5 #include<math.h>

  6 #include<iostream>

  7 #include<string>

  8 #include<algorithm>

  9 #include<vector>

 10 #include<queue>

 11 #include<stack>

 12 #include<map>

 13 using namespace std;

 14 #define LL __int64

 15 #define pii pair<int,int>

 16 #define Max(a,b) ((a)>(b)?(a):(b))

 17 #define Min(a,b) ((a)<(b)?(a):(b))

 18 #define mem(a,b) memset(a,b,sizeof(a))

 19 #define lson l,mid,rt<<1

 20 #define rson mid+1,r,rt<<1|1

 21 const int N=15,M=100000,INF=0x3f3f3f3f,MOD=100000000;

 22 const double DNF=100000000000;

 23  

 24 int a[N][11],b[N][11],d[N];

 25 int T,n,m;

 26  

 27 int geta(int n)

 28 {

 29     int i,j,t,num[N],len=0,ret=0,ok=0;

 30     do{num[len++]=n%10;}

 31     while(n/=10);

 32     for(i=len-1;i>=0;i--){

 33         for(j=0;j<num[i];j++)ret+=a[i][j];

 34         if(num[i]==8)break;

 35         if(num[i]==3){

 36             for(t=1,i--;i>=0;i--){

 37                 if(ok)num[i]=9;

 38                 if(num[i]==8)ok=1;

 39                 t+=(num[i]-(num[i]>=8?1:0))*d[i];

 40             }

 41             ret+=t;

 42         }

 43     }

 44     return ret;

 45 }

 46  

 47 int getb(int n)

 48 {

 49     int i,j,t,num[N],len=0,ret=0,ok=0;

 50     do{num[len++]=n%10;}

 51     while(n/=10);

 52     for(i=len-1;i>=0;i--){

 53         for(j=0;j<num[i];j++)ret+=b[i][j];

 54         if(num[i]==3)break;

 55         if(num[i]==8){

 56             for(t=1,i--;i>=0;i--){

 57                 if(ok)num[i]=9;

 58                 if(num[i]==3)ok=1;

 59                 t+=(num[i]-(num[i]>=3?1:0))*d[i];

 60             }

 61             ret+=t;

 62         }

 63     }

 64     return ret;

 65 }

 66  

 67 int main()

 68 {

 69  //   freopen("in.txt","r",stdin);

 70     int i,j,k;

 71     d[0]=1;

 72     for(i=1;i<=9;i++)d[i]=d[i-1]*9;

 73     a[0][3]=1,b[0][8]=1;

 74     for(i=1;i<=9;i++){

 75         for(j=0;j<=9;j++){

 76             if(j==8)continue;

 77             if(j!=3)for(k=0;k<=9;k++){

 78                 if(k==8)continue;

 79                 a[i][j]+=a[i-1][k];

 80             }

 81             else a[i][j]=d[i];

 82         }

 83     }

 84     for(i=1;i<=9;i++){

 85         for(j=0;j<=9;j++){

 86             if(j==3)continue;

 87             if(j!=8)for(k=0;k<=9;k++){

 88                 if(k==3)continue;

 89                 b[i][j]+=b[i-1][k];

 90             }

 91             else b[i][j]=d[i];

 92         }

 93     }

 94     scanf("%d",&T);

 95     while(T--)

 96     {

 97         scanf("%d%d",&n,&m);

 98         n--;

 99      printf("%d\n",geta(m)-geta(n)+getb(m)-getb(n));

100     }

101     return 0;

102 }

 

你可能感兴趣的:(dp)