算法
(暴力枚举情况)
y总在视频讲解的时候思路是这个思路,但是代码缩减得太快,一通操作我愣是没看懂,只得枚举全部情况。
枚举情况:
//假设n = abcdefg
//求每一位是t的情况是多少
//当 t == 0 时,不能有前导全0
//d不能在a的位置
//当 d == t 时: (001~abc-1)0*10^(efg) + abc0(000~efg)
//当 d > t 时: (001~abc)t*10(efg)
//当 d < t 时,不存在
//当 t != 0时,可以有前导全0
//当 d == t 时: (000~abc-1)t*10^(efg) + abct(000~efg)
//当 d > t 时: (000~abc)t*10^(efg)
//当 d < t 时: (000~abc-1)t*10^(efg)
C++ 代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int power[10] ;
void initPower(){
power[0] = 1;
for(int i = 1 ; i < 10 ; i++ )
power[i] = 10*power[i-1];
}
int get(vector<int>& nums , int l , int r){ //得到指定区间的数值是多少
//if( l > r ) return 0 ;
int res = 0 ;
for(int i = l ; i <= r ; i++ )
res = res*10 +nums[i];
return res;
}
int count(int n , int k){ //1~n中数字k出现的次数
vector<int> nums;
while( n ){ //枚举每一位 54321 -> 12345
nums.push_back( n%10 );
n /= 10 ;
}
reverse(nums.begin(),nums.end());
int ans = 0 ;
int t = nums.size();
for(int i = 0 ; i < t ; i++ ){//枚举k在每一位中出现的次数
int last = t-1-i ;//i之后有几位
if( k == 0 ){ //找0
if(nums[i] == 0) //不能有前导0:1~get(0~i-1) + get(0~i-1)0get(i+1~yyy)
ans += (get(nums,0,i-1)-1)*power[last] + get(nums,i+1,t-1)+1;
else if(nums[i] > 0)
ans += get(nums,0,i-1)*power[last];
// else nums[i]不会小于0,所以不会实施
// ans += (get(nums,0,i-1)-1)*power[last];
}else{
if(nums[i] == k) //可以有前导0:0~get(0~i-1)->get(0~i-1)
ans += get(nums,0,i-1)*power[last] + get(nums,i+1,t-1)+1;
else if(nums[i] > k)
ans += (get(nums,0,i-1)+1)*power[last];
else //nums[i] < k
ans += get(nums,0,i-1)*power[last];
}
}
return ans ;
}
int main()
{
int a , b ;
initPower();
while(cin >> a >> b && a && b){
if( b > a ) swap(a, b);
for(int i = 0 ; i < 10 ; i ++ )
cout << count(a , i) - count(b-1,i) << " " ;
cout << endl;
}
return 0 ;
}
这也太复杂了!!!
hh
哈哈哈,已经缩减。完全按照枚举情况来写了。