牛客网

时间限制: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

      • next®。 输入描述:

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

输出描述:

一个数字表示答案。

示例1
输入

2 7

输出

33

示例2
输入

7 7

输出

7

题意:
打表出奇迹
你可以提前打好表,记录在数组里
或者现打表,有两个方法
一个是用vector,
或者自身递归查找,存在pre中
打完表后,直接从l开始对比数到r
直接if判断然后sum加有点慢
你可以看每两个pre之间的数最后都做一样相加,比如47~74之间(不含47)的数都算作74,那有多少个数?就是74-47+1,然后直接乘74,加起来就ok了
注意注意!!!不要忘了longlong,可坑死我了

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll pre[100000];
int cnt=0;
int min(ll a,ll b)
{
   
	return a>b?b:a;
}
void dfs(ll n)
{
   
	if(n>1e10+2)return ; 
	pre[cnt++]=n;
	dfs(n*10+4);
	dfs(n*10+7);
}
/* void dfs(ll x) { if(n-1e9>0)return ; q.push_back((x<<3)+(x<<1)+4); dfs((x<<3)+(x<<1)+4); dfs((x<<3)+(x<<1)+7); q.push_back((x<<3)+(x<<1)+7); } dfs(0); sort(q.begin(),q.end()); q.push_back(4444444444); */
int main()
{
   
	ll r,l;
	scanf("%lld %lld",&l,&r);
	dfs(0);
	sort(pre+1,pre+1+cnt);
// cout<<pre[cnt-1]<<endl;
	ll sum=0;
	ll ant=0;
	for(ll i=l;i<=r;)
	{
   
	// if(i>pre[ant])ant++;
	// sum+=pre[ant];
		while(i>pre[ant])ant++;
		sum+=pre[ant]*(min(r,pre[ant])-i+1);
		i=pre[ant]+1;
	}
	printf("%lld\n",sum);
}