1. 程式人生 > 實用技巧 >【Hoj1983】美麗數Beautiful numbers

【Hoj1983】美麗數Beautiful numbers

Description

在他看來,一個正整數是美麗的,當且僅當它可以被它的每個非零數字整除。
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.

Input

Multiple test cases.
Each line contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 · 10^18).

Output

One line specifies the answer.

Sample Input

1 9
12 15

Sample Output

9
2


思路

  • 2520是1~9的最小公倍數,2520共有幾十個約數
  • 注意long long
  • hash

程式碼

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int bit[22],hash[2525],cnt;
long long dp[22][2525][50],a,b;
long long gcd(long long a,long long b){return !b?a:gcd(b,a%b);}//最大公因數 
long long lcm(long long a,long long b){return a/gcd(a,b)*b;}//最小公倍數 
long long dfs(int x,int num,int mod,int flag)
{
	if(x==1) return num%mod==0;
	if(!flag&&dp[x][num][hash[mod]]!=-1) return dp[x][num][hash[mod]];
	int count=flag?bit[x-1]:9; long long ans=0;
	for(int i=0;i<=count;++i) ans+=dfs(x-1,(num*10+i)%2520,i?lcm(mod,i):mod,flag&&i==count);
	return flag?ans:dp[x][num][hash[mod]]=ans;
}
long long start(long long x)
{
	int len=0;
	for(;x;x/=10) bit[++len]=x%10;
	return dfs(len+1,0,1,1);
}
signed main()
{
	memset(dp,-1,sizeof(dp));
	for(int i=1;i*i<=2520;++i)
		if(2520%i==0) hash[i]=++cnt,hash[2520/i]=++cnt;
	while(~scanf("%lld%lld",&a,&b)) printf("%lld\n",start(b)-start(a-1));
	return 0;
}