您的位置:首页 > 编程语言

牛客练习赛13-B题(另带一份大佬的代码,细节值得学习)

2018-03-16 21:06 399 查看
题目链接:https://www.nowcoder.com/acm/contest/70/B

题目分析:把所有幸运数按从小到大都求出来,打个表。

代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: