牛客练习赛13-B题(另带一份大佬的代码,细节值得学习)
2018-03-16 21:06
399 查看
题目链接:https://www.nowcoder.com/acm/contest/70/B
题目分析:把所有幸运数按从小到大都求出来,打个表。
代码:
分享一个大佬写的代码:http://blog.csdn.net/wyxeainn/article/details/79588812
代码如下:
题目分析:把所有幸运数按从小到大都求出来,打个表。
代码:
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <string> #include <stdlib.h> #include <algorithm> using namespace std; long long lucky[100000],ans=0; long long flag,flag1,sum=0,l,r; int main() { scanf("%lld%lld",&l,&r); lucky[sum++]=4; lucky[sum++]=7; lucky[sum++]=44; lucky[sum++]=47; lucky[sum++]=74; lucky[sum++]=77; flag=2; for(int i=3; i<=10; i++) { flag1=pow(2,i-1); for(int j=flag; j<flag+flag1; j++) { lucky[sum++]=lucky[j]*10+4; lucky[sum++]=lucky[j]*10+7; } flag+=pow(2,i-1); } long long pos=l,j=l; for(long long i=0; i<2046; ) { if(j<=lucky[i]) { j++; if(j==r+1) { ans=ans+(j-pos)*lucky[i]; break; } } else { ans=ans+(j-pos)*lucky[i]; pos=j; i++; if(j==r+1) break; } } printf("%lld\n",ans); return 0; }
分享一个大佬写的代码:http://blog.csdn.net/wyxeainn/article/details/79588812
代码如下:
解题思路:首先使用dfs求解出所有的幸运数字,题目给出 数字数据范围为10亿,则最多10位由4和7组成的数字就是 极限,对于每一位,可以是4,也可以是7,用递归进行计算, 并保留所有的中间结果,一次递归的过程求出所有幸运数字。 大概有一千多个,然后对他们进行排序,则对于给出的L,R, 可以知道两个相邻幸运数字间的那些数字都对答案贡献较小 的那个幸运数字,就这样跳着求。只要求出大于等于L幸运数 字的位置,之后便不用查找,通过自增得来就可以了。 变量含义: cnt:t数组的变量,在存储幸运数字时使用 t:t数组用来存储所有的幸运数字 方法含义: dfs:递归求幸运数字,dfs(x,num)x代表当前这位是x getNext:使用二分查找第一个大于等于i的幸运数字的位置 ***************************************************************************/ #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const long long maxn = 4444444444; long long cnt,t[1000]; void dfs(int x,long long num) { num = num*10 + x; if(num > maxn) { return; } t[cnt++] = num; //存储中间的每一个数 dfs(4,num); dfs(7,num); } int getNext(long long i){ int pos = lower_bound(t,t+cnt,i)-t; return pos; } int main() { cnt = 0; dfs(4,(long long)0); dfs(7,(long lo 4000 ng)0); //printf("%d\n",cnt); sort(t,t+cnt); //排序,二分查找要求数组元素有序 long long L,R,temp; while(~scanf("%lld%lld",&L,&R)) { //防止L>R的情况,但本题此判断无用,因为题目说了L<=R if(L>R) { temp = L; L = R; R = temp; } long long ans = 0; long long i = L; long long x; long long j = getNext(i); //求起始位置。 while(true) { x = t[j]; if(x >= R) { ans += (R-i+1)*x; break; } ans += (x-i+1)*x; i = x+1; j++; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 最值得阅读学习的 10 个 C 语言开源项目代码
- 最值得学习阅读的10个C语言开源项目代码
- HTML5代码学习:值得收藏的HTML5代码片段
- easyui编程中值得学习的一些代码
- Unity学习笔记13——代码动态加载Prefab预设体
- 牛客练习赛13 A 幸运数字Ⅰ 【暴力】
- 十个最值得阅读学习的C开源项目代码
- 牛客练习赛13 --E(dp)
- 牛客练习赛13 D 题 幸运数字IV 【康拓逆展开 + 思维】
- 最值得学习阅读的10个C语言开源项目代码
- 开始学习Objective-C一些代码细节解释
- 最值得学习阅读的10个C语言开源项目代码
- muduo库的学习2--Socket的基本设计---代码细节
- java学习【知识点及代码13】
- 非常不错的俄罗斯方块程序代码,值得学习
- 牛客练习赛13-幸运数字I
- 牛客练习赛13
- 牛客练习赛13 E-龟兔跑步
- 值得学习的一段代码
- FVC/JEM代码学习13 : SAOProcess