牛客练习赛13 幸运数字Ⅱ

链接:https://www.nowcoder.com/acm/contest/70/B
来源:牛客网

题目描述

定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。

输入描述:

两个整数l和r (1 <= l <= r <= 1000,000,000)。

输出描述:

一个数字表示答案。
示例1

输入

2 7

输出

33
示例2

输入

7 7

输出

7

分析:找规律,发现10到100的幸运数是0到10的所有幸运数十位上加4,
再十位上加7,100到1000的幸运数是10到100的所有幸运数百位上加4,
再百位上加7,当前阶段的幸运数总数总为前一阶段的2倍,然后打表,
把10^10(注意幸运数应该大于10^9)以内的幸运数记录下来,求和的时候用乘法就可以了。

#include<cstdio>
#include<algorithm>
using namespace std;
long long a[98000],N=3;
int num[20]={1,2,4,8,16,32,64,128,256,512,1024};
long long Pow[20];
void f()
{
    Pow[0]=1;
    for(int j=1;j<12;j++) Pow[j]=10*Pow[j-1];
    a[1]=4;a[2]=7;
    int i=1;
    for(;i<11;i++)
    {
        int k=N-1;
        for(int j=N-num[i];j<=k;j++)
        a[N++]=a[j]+4*Pow[i];
        for(int j=k+1-num[i];j<=k;j++)
        a[N++]=a[j]+7*Pow[i];
    }
}

int main()
{
    long long l,r;
    f();
    scanf("%lld%lld",&l,&r);
    long long ans=0;
    while(l<=r)
    {
        long long temp=a[lower_bound(a,a+N,l)-a];
        if(temp<=r)
        {
            ans+=temp*(temp-l+1);
            l=temp+1;
        }
        else
        {
            ans+=temp*(r-l+1);
            break;
        }
    }
    printf("%lld
",ans);
    return 0;
}
View Code


原文地址:https://www.cnblogs.com/ACRykl/p/8586270.html