1853: [Scoi2010]幸运数字
Time Limit: 2 Sec Memory Limit: 64 MB
Submit: 2947 Solved: 1096
[Submit][Status][Discuss]
Description
在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。 现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。
Input
输入数据是一行,包括2个数字a和b
Output
输出数据是一行,包括1个数字,表示在闭区间[a, b]内“近似幸运号码”的个数
Sample Input
【样例输入1】
1 10
【样例输入2】
1234 4321
Sample Output
【样例输出1】
2
【样例输出2】
809
HINT
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
Source
卧槽这题不跟刚才那题一样一样的嘛【惊呆脸.jpg】貌似要加一些神奇的优化,比如b数组要从大到小存,酱紫有利于dfs剪枝???
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=3005; 5 LL l,r,a[MAX],b[MAX],ans; 6 bool p[MAX]; 7 void get(LL x){ 8 if (x>r) return; 9 if (x) a[++a[0]]=x; 10 get(x*10+6),get(x*10+8); 11 } 12 LL gcd(LL x,LL y){return y==0?x:gcd(y,x%y);} 13 void dfs(LL x,LL y,LL lcm){ 14 if (x>b[0]){ 15 if (y&1) ans+=r/lcm-(l-1)/lcm; 16 else if (y) ans-=r/lcm-(l-1)/lcm; 17 return; 18 } 19 dfs(x+1,y,lcm); 20 LL g=gcd(b[x],lcm); 21 lcm/=g; 22 if (r/lcm<b[x]) return; 23 lcm*=b[x]; 24 dfs(x+1,y+1,lcm); 25 } 26 int main(){ 27 freopen ("lucky.in","r",stdin);freopen ("lucky.out","w",stdout); 28 int i,j; 29 scanf("%lld%lld",&l,&r); 30 get(0);sort(a+1,a+a[0]+1); 31 for (i=1;i<=a[0];i++) 32 if (!p[i]){ 33 b[++b[0]]=a[i]; 34 for (j=i+1;j<=a[0];j++) if (a[j]%a[i]==0) p[j]=true; 35 } 36 for (i=1;i<=b[0]/2;i++) swap(b[i],b[b[0]-i+1]); 37 dfs(1,0,1); 38 printf("%lld",ans); 39 return 0; 40 }
时间: 2024-10-25 22:29:34