原题链接:登录—专业IT笔试面试备考平台_牛客网
解题思路:本题可以先遍历1到1e6,标记“令人讨厌的数”个数的前缀和。然后直接输出前缀和数组第m位的值减去第n-1位的值,得到这个区间内令人讨厌的数的和。
而标记“令人讨厌的数”可以对每一个数检查其最后两位是否为38或者最后一位为4,然后每次舍弃末尾一位。如果整个数都没有这种情况,那么他就不是。有的话就标记。
AC代码:
#include<bits/stdc++.h>
using namespace std;
long long m,n,pre_sum[1000000];//m和n为题目原意,pre_sum为前缀和,记录有几个讨厌的数
int main(){
for(int i=1;i<=1000000;i++){//预处理1到1e6的令人讨厌的数
int buffer;
buffer=i;
while(buffer){//循环到buffer每一位取完
if(buffer%10==4||buffer%100==38){//如果最后一位为4或者最后两位为38,则这个数是令人讨厌的,标记并退出循环
pre_sum[i]=1;
break;
}
buffer/=10;//往前移动一位
}
pre_sum[i]+=pre_sum[i-1];//前缀和
}
while(1){//O(1)查询
cin>>n>>m;
if(n==0&&m==0) break;
cout<<pre_sum[m]-pre_sum[n-1]<<endl;
}
return 0;
}