1. 没有字母的数
输入:
3
1 16
10 43
100 900
输出:
10
20
321
法1:将输入的10进制转化成16进制,因为题目要求带字母的数不统计,所以此时的16进制数可以当成10进制数进行减法运算,还要注意一个问题:输入的数字16进制格式带字母怎么处理,左端点找第一个大于他不带字母的数,右端点找第一个小于他不带字母的数。
#include<iostream>
#include<cmath>
using namespace std;
int t;
int a[10],b[10];
int main()
{
cin>>t;
int l,r;
while(t--)
{
scanf("%d %d",&l,&r);
int k1=0,k2=0;
while(l)
{
a[k1++]=l%16;
l=l/16;
}
while(r)
{
b[k2++]=r%16;
r=r/16;
}
int f1=1,f2=1;
int sum1=0,sum2=0;//1->后
for(int i=k2-1;i>=0;i--)
{
if(f1&&b[i]<=9)
{
sum1=sum1*10;
sum1+=b[i];
}
else
{
f1=0;
sum1=sum1*10;
sum1+=9;
}
}
int mm=-1;
for(int i=k1-1;i>=0;i--)
{
if(a[i]>9)
{
mm=i+1;
break;
}
}
for(int i=k1-1;i>=0;i--)
{
if(mm==k1)
{
sum2=pow(10,k1);
break;
}
else if(f2&&mm!=i)
{
sum2=sum2*10;
sum2+=a[i];
}
else
{
f2=0;
sum2=sum2*10;
sum2+=a[i]+1;
sum2=sum2*pow(10,i);
break;
}
}
//cout<<sum2<<" "<<sum1<<endl;
cout<<sum1-sum2+1<<endl;
}
return 0;
}
法2:前缀和,先预处理,10的6次方个数,没有字母的数加一,有字母的不变,用前缀和数组来存
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N];
int check(int x)
{
while(x)
{
if(x%16>=10) return 0;
x/=16;
}
return 1;
}
int main()
{
for(int i=1;i<=N;i++){
if(check(i)) a[i]=a[i-1]+1;
else a[i]=a[i-1];
}
int t;
cin>>t;
while(t--)
{
int l,r;
cin>>l>>r;
cout<<a[r]-a[l-1]<<endl;
}
return 0;
}