基准时间限制:1 秒 空间限制:131072 KB 分值: 10
难度:2级算法题
给出一段区间a-b,统计这个区间内0-9出现的次数。
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
Input
两个数a,b(1 <= a <= b <= 10^18)
Output
输出共10行,分别是0-9出现的次数
Input示例
10 19
Output示例
1 11 1 1 1 1 1 1 1 1
51nod 1009的进阶版,还是从小到大算起。
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <ctime>;
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x3fffffffffffffff
const ll mod = 1e9 + 7;
const int maxn = 1e7;
ll n1, n2;
ll dp[20];
void init()
{
memset(dp, 0, sizeof(dp));
ll i;
for (i = 1; i <= 19; i++)
{
dp[i] = i*pow(10, i - 1);
}
}
ll count(ll x,int nu)
{
ll pre = 0;
ll nx = x;
ll result = 0;
ll len = 0;
ll digit = 0;
ll radix = 1;
ll tail = 0;
while (x != 0)
{
digit = x % 10;
x = x / 10;
++len;
if (digit > nu)
{
result += radix + digit*dp[len - 1];//radix就代表10的多少多少次方,这个时候重复算反而是对的
}
else if (digit == nu)
{
result += tail + 1 + digit*dp[len - 1];//+1是代表取的那个整数
}
else
{
result += digit*dp[len - 1];
}
tail = tail + digit*radix;
radix *= 10;
}
if (nu == 0)
{
ll m = 1;
while (nx != 0)
{
result -= m;
m = m * 10;
nx = nx / 10;
}
}
return result;
}
void solve()
{
cin >> n1 >> n2;
int i;
for (i = 0; i <= 9; i++)
{
cout << count(n2, i) - count(n1 - 1, i) << endl;
}
}
int main()
{
init();
solve();
return 0;
}