分类讨论
下面只是一个例子
从1~abcdefg中1在第四位出现的次数
从这个例子可以看出要想求出n~abcdefg中1出现的次数只需要求
1~abcdefg 中 1从第一位到abcdefg最后一位所出现次数的总和 减去
1~n-1 中 1从第一位到n-1 最后一位所出现次数的总和
就可以得到所要的结果
那么在这中是不是有一些特殊情况???
就如当这个为第一位时怎么求??
这个时候就不能和例子中上面的分类一样,要按照下面的分类来求
这个可以举一个例子就能想明白
比如在1~abcdefg中1在第一位出现的次数
它在前面没有数,就只能考虑在a>1 , a = 1 , a < 1 时这三种情况下所出现的次数 也就是下面的分类条件
除了上面的内容还有其它的特殊情况
当所要求的数为0在第n位上所出现的个数时 在第一位上就要直接跳过
比如求0在从1~abcdefg第一位所出现的个数a这一位必然不是0
同时在这个情况下
将这几类想明白了这道题也快解决了
下面是代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 15;
int num[N];
int get_1_n(int l , int r){
int res = 0 ;
for(int i = l ; i >= r ; i --){
res = res * 10 + num[i];
}
return res;
}
int pow10(int x){
int res = 1 ;
while(x--){
res *= 10;
}
return res;
}
int work(int n , int x){
if(n == 0 ) return 0;//当n=0时直接返回0
int len = 0 ;
while(n){
num[++len] = n % 10;
n /= 10;
}
int res = 0;
if(x != 0){
for(int i = len ; i > 0 ; i-- ){
if(i < len ) res += (get_1_n(len , i + 1) )* pow10(i-1);
if(num[i] == x) res += get_1_n(i-1 , 1) +1;
else if(num[i] > x)res += pow10(i - 1);
else res += 0;
}
}
else {
for(int i = len -1; i > 0; i--){
res += (get_1_n(len , i + 1) - 1) * pow10(i-1);
if(num[i] == x) res += get_1_n(i-1 , 1) + 1;//在x = 0 时别忘了其取值的个数时变化的
else if(num[i] > x)res += pow10(i - 1);
else res += 0;
}
}
return res;
}
int main(){
int a , b ;
while(cin>>a>>b && (a | b)){
if(a > b)swap(a , b); //判断a和b的大小使b为最大值
for(int i = 0 ; i < 10 ; i ++){
int res = work(b , i) - work(a-1 , i);
cout<<res<<" ";
}
cout<<endl;
}
return 0;
}
这旧史史
orz