Beautiful numbers
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Beautiful numbers相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/CodeForces-55D
题意:有T组数据,每组数据输入两个数,a,b,输出在a-b区间有多少个美丽数
美丽数:规定一个数它能被它各个位上非0数整除,即为美丽数。
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define LL long long 7 using namespace std; 8 int num[2550],cnt=0; 9 int lim[50],lct=0; 10 LL f[24][2520][50]; 11 LL n,m; 12 LL gcd(LL a,LL b) 13 { 14 if(!b) 15 return a; 16 return gcd(b,a%b); 17 } 18 LL dp(int pos,int smm,int lcm,bool flag) 19 { 20 ///当前位置 当前和 当前最小公倍数 是否在上界(flag==0时达到上界) 21 if(pos==0) 22 return smm%lcm==0;///当前的和能整除当前最小公倍数则返回1 23 if(flag==0&&f[pos][smm][num[lcm]]!=-1) 24 return f[pos][smm][num[lcm]]; 25 LL res=0; 26 int limit=9; 27 if(flag) 28 limit=lim[pos]; 29 for(int i=0;i<=limit;i++)///0到limit,即能完成找出0到数x的全部beautifui numbers 30 { 31 int psmm=(smm*10+i)%2520; 32 int plcm=lcm; 33 if(i) 34 { 35 plcm=lcm/gcd(lcm,i)*i; 36 } 37 res+=dp(pos-1,psmm,plcm,flag&&i==limit);///flag&&i==limit的意思是比如100要把100以前所有的数也要算一遍,控制flag是否等于0判断是否让limit=lim[pos],例如100,第一位limit=1,进如for循环,i=0时,flag=0,再次进如dp是limit才能等于9 38 } 39 if(flag==0) 40 f[pos][smm][num[lcm]]=res; 41 return res; 42 } 43 LL divi(LL x)///该函数是求在x之前有多少个beautiful number 44 { 45 lct=0;///lct是记录x有多少位 46 while(x) 47 { 48 lim[++lct]=x%10;///lim数组是记录各个位上的数 49 x/=10; 50 printf("%d\n",lim[lct]); 51 } 52 return dp(lct,0,1,1); 53 } 54 int main() 55 { 56 int t; 57 for(i=1;i<=2520;i++) 58 { 59 if(2520%i==0) 60 num[i]=++cnt; 61 } 62 memset(f,-1,sizeof(f)); 63 scanf("%d",&t); 64 while(t--) 65 { 66 scanf("%I64d%I64d",&n,&m); 67 printf("%I64d\n",divi(m)-divi(n-1)); 68 } 69 }
以上是关于Beautiful numbers的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 55D Beautiful numbers (数位DP)
CodeForces - 55D Beautiful numbers
Codeforces Round #604 (Div. 2) B. Beautiful Numbers(双指针)