您的位置:首页 > 其它

ACdream 完美数 数位DP

2013-03-25 16:53 603 查看
  题目链接:http://www.acdream.net/problem.php?id=1083

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

//STATUS:C++_AC_20MS_1512KB
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define LL __int64
#define pii pair<int,int>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N=15,M=100000,INF=0x3f3f3f3f,MOD=100000000;
const double DNF=100000000000;

int a
[11],b
[11],d
;
int T,n,m;

int geta(int n)
{
int i,j,t,num
,len=0,ret=0,ok=0;
do{num[len++]=n%10;}
while(n/=10);
for(i=len-1;i>=0;i--){
for(j=0;j<num[i];j++)ret+=a[i][j];
if(num[i]==8)break;
if(num[i]==3){
for(t=1,i--;i>=0;i--){
if(ok)num[i]=9;
if(num[i]==8)ok=1;
t+=(num[i]-(num[i]>=8?1:0))*d[i];
}
ret+=t;
}
}
return ret;
}

int getb(int n)
{
int i,j,t,num
,len=0,ret=0,ok=0;
do{num[len++]=n%10;}
while(n/=10);
for(i=len-1;i>=0;i--){
for(j=0;j<num[i];j++)ret+=b[i][j];
if(num[i]==3)break;
if(num[i]==8){
for(t=1,i--;i>=0;i--){
if(ok)num[i]=9;
if(num[i]==3)ok=1;
t+=(num[i]-(num[i]>=3?1:0))*d[i];
}
ret+=t;
}
}
return ret;
}

int main()
{
//   freopen("in.txt","r",stdin);
int i,j,k;
d[0]=1;
for(i=1;i<=9;i++)d[i]=d[i-1]*9;
a[0][3]=1,b[0][8]=1;
for(i=1;i<=9;i++){
for(j=0;j<=9;j++){
if(j==8)continue;
if(j!=3)for(k=0;k<=9;k++){
if(k==8)continue;
a[i][j]+=a[i-1][k];
}
else a[i][j]=d[i];
}
}
for(i=1;i<=9;i++){
for(j=0;j<=9;j++){
if(j==3)continue;
if(j!=8)for(k=0;k<=9;k++){
if(k==3)continue;
b[i][j]+=b[i-1][k];
}
else b[i][j]=d[i];
}
}
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
n--;
printf("%d\n",geta(m)-geta(n)+getb(m)-getb(n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: