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 }

 

posted @ 2013-03-25 16:53  zhsl  阅读(277)  评论(0编辑  收藏  举报