链接:https://ac.nowcoder.com/acm/contest/70/B
来源:牛客网
幸运数字Ⅱ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + … + next(r - 1) + next®。
输入描述:
两个整数l和r (1 <= l <= r <= 1000,000,000)。
输出描述:
一个数字表示答案。
示例1
输入
复制
2 7
输出
复制
33
示例2
输入
复制
7 7
输出
复制
7
这一题跟杭电的不要62很像,我们可以预先将10,100,1000…10000000000的4,7组合处理,为的是方便查找查询的左右端点处于哪一个位置上。
所以我们用dfs将1e10内所有的4,7组合从小到大的排序,然后二分查找l,r的相对位置,然后我们知道就是这个区间的数的个数有min(a[i],r)-l+1,然后乘于幸运数字a[i],所以ans=(min(a[i],r)-l+1)*a[i];当然l需要更新。
比如234—1234 234的下一个幸运数是444,1235的下一个幸运数是4444,
我们就知道234到444之间有min(444,1234)-l+1=211个数,然后乘以444,就是这个区间的值。所以我们只需要找到当前数的下一个幸运数即可
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[10000000];
int cnt=2;
void dfs(ll x)
{
if(x>10000000000)
{
return ;
}
if(x>10)
a[cnt++]=x;
dfs(x*10+4);
dfs(x*10+7);
}
int main()
{
a[0]=4;
a[1]=7;
dfs(4);
dfs(7);
a[cnt]=4444444444;//是因为大于1e10就没法查了,所以先加一个其上限
sort(a,a+cnt+1);
ll l,r;
cin>>l>>r;
int L=lower_bound(a,a+cnt+1,l)-a;
int R=lower_bound(a,a+cnt+1,r)-a;
ll ans=0;
for(int i=L;i<=R;i++)
{
ans+=(min(a[i],r)-l+1)*a[i];
l=a[i]+1;
}
cout<<ans<<endl;
return 0;
}