TZOJ5144:幸运数字
描述
定义幸运数字为数位(十进制)只含有 4 和 7 的数字。例如:4,7,47,777 等是幸运数字;5,72 等就不是幸运数字。
定义函数 next(n)表示大于等于 n 的最小的幸运数字,现在给你一个区间[a, b]让你求 S(a,b)=next(a)+next(a+1)+…+next(b-1)+next(b)的值。
输入
第一行输入一个整数 T (T ≤ 10),表示测试样例个数,对于每个测试样例,输入两个空格分开的整数 a,b(1 ≤ a ≤ b ≤ 109 ) 表示给出的区间是[a, b]。
输出
对于每个测试样例,输出一个整数,表示 S(a,b)的值,每个测试数据的输出占一行。
‘------------------------------------------------------------------------------------------------------------------------‘
其实就是个区间和问题,刚开始以为是道二进制题目,后面没有什么好的思路,就只能把范围里1-10^9的幸运数预处理出来放进数组里。我们假定数组为map[],k为初始下标
然后就是循环a,b之间的数,首先判断map[k]是否小于a,如果小于则再进一步讨论b是否小于map[k];
如果都小于则区间和直接为map[k](b-i+1),如果b大于map[k]则[a,map[k]]之间和为map[k](map[k]-i+1);
数据代码就不打上去了
!还要注意b的范围10^9,所以当区间某点范围大于777777777则下一个最小幸运数为4444444444
int main(int argc, char const *argv[])
{
int n;
scanf("%d",&n);
while(n--){
int a,b;
int k=0;
scanf("%d %d",&a,&b);
ll sum=0;
for(int i=a;i<=b;i++){
if(i>777777777){ //如果大于范围里的最大幸运数
sum+=4444444444*(b-i+1);
i=b;
}
else if(i<=map1[k]){ //求大于i的最小幸运数,如果当前数组小标对应的数小于则判断b和当前幸运数的关系
if (map1[k]<= b){
sum += map1[k]*(map1[k]-i+1);
i = map1[k];
}
else{
sum += map1[k]*(b-i+1);
i = b;
}
}
else{ //否则求出下一个最小幸运数
while(1){
k ++;
if (i <= map1[k]){
sum += map1[k];
break;
}
}
}
}
printf("%lld\n",sum);
}
return 0;
}
我也不知道别人提交的代码为什么这么短。这题不知道还有什么解法。