P2567 [SCOI2010]幸运数字
题目描述
在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。
现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。
输入输出格式
输入格式:
输入数据是一行,包括2个数字a和b
输出格式:
输出数据是一行,包括1个数字,表示在闭区间[a, b]内“近似幸运号码”的个数
输入输出样例
输入样例
1 10
输出样例
2
说明
对于100%的数据,保证1<=a<=b<=10000000000
思路:
代码:
1 //#include"bits/stdc++.h" 2 #include <sstream> 3 #include <iomanip> 4 #include"cstdio" 5 #include"map" 6 #include"set" 7 #include"cmath" 8 #include"queue" 9 #include"vector" 10 #include"string" 11 #include"cstring" 12 #include"time.h" 13 #include"iostream" 14 #include"stdlib.h" 15 #include"algorithm" 16 #define db double 17 #define ll long long 18 #define vec vector<ll> 19 #define mt vector<vec> 20 #define ci(x) scanf("%d",&x) 21 #define cd(x) scanf("%lf",&x) 22 #define cl(x) scanf("%lld",&x) 23 #define pi(x) printf("%d\n",x) 24 #define pd(x) printf("%f\n",x) 25 #define pl(x) printf("%lld\n",x) 26 //#define rep(i, x, y) for(int i=x;i<=y;i++) 27 #define rep(i,n) for(int i=0;i<n;i++) 28 const int N = 1e5 + 5; 29 const int mod = 1e9 + 7; 30 const int MOD = mod - 1; 31 const int inf = 0x3f3f3f3f; 32 const db PI = acos(-1.0); 33 const db eps = 1e-10; 34 using namespace std; 35 ll a[N],b[N]; 36 bool v[N]; 37 int m=0,n=0; 38 ll l,r,ans=0; 39 ll gcd(ll x,ll y){ 40 return y==0?x:gcd(y,x%y); 41 } 42 void init(ll x){ 43 if(x>r) return ; 44 else if(x>0) a[++m]=x;//0不加入 45 init(x*10+6); 46 init(x*10+8); 47 } 48 void dfs(int x,int y,ll z)//表示:前x个数字中选y个数字时的lcm为z 49 { 50 if(x==n){ 51 if(y&1) ans+=r/z-(l-1)/z;//奇数加 52 if(y%2==0&&y!=0) ans-=r/z-(l-1)/z;//偶数减 53 return; 54 } 55 dfs(x+1,y,z); 56 ll s=z/gcd(a[x+1],z); 57 if((db(s)*a[x+1])<=r) dfs(x+1,y+1,a[x+1]*s);//一个剪枝:lcm<=r 58 } 59 int main() 60 { 61 cl(l),cl(r); 62 init(0); 63 sort(a+1,a+m+1); 64 for(int i=1;i<=m;i++){//去掉内部倍数情况 65 if(!v[i]){ 66 b[++n]=a[i]; 67 for(int j=i+1;j<=m;j++) 68 if(a[j]%a[i]==0) v[j]=1; 69 } 70 } 71 for(int i=1;i<=n;i++) a[n+1-i]=b[i];//数字从大到小排 72 dfs(0,0,1); 73 pl(ans); 74 return 0; 75 }