1 solutions
-
6
题意
举个例子:
11
算两个1
思路
根据排列组合知识,
0~10^(i+1)-1
中,每个数码出现的次数一样,为i*10^(i-1)
。具体推法见注释。
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 15; ll b[N],p[N] = {1},a[N] = {0}; /* b[i]:0 ~ 10^(i+1)-1 间每个数码出现次数(包括前导零) p[i]:10^i */ void init(){ for (int i = 1;i < N;i++){ p[i] = p[i - 1] * 10; b[i] = b[i - 1] * 10 + p[i - 1]; // b[i] = i * p[i - 1]; } } void solve(ll x){ ll t[N]; copy(begin(a),end(a),begin(t)); memset(a,0,sizeof a); int len = 0,num[N] = {0}; while (x){ num[++len] = x % 10; x /= 10; } // 设 x=2617 for (int i = len;i > 0;i--){ // 以 i=n 为例 for (int j = 0;j <= 9;j++){ // j 小于 2 的都有 10^3(10^(i-1))次 if (j < num[i]) a[j] += p[i - 1]; // 无论 j 是什么,它在第 3(i-1)位一定是满的 a[j] += num[i] * b[i - 1]; } // 2(num[i])的出现次数是 618(记得算 2000)次 ll num_10 = 0; for (int j = i - 1;j > 0;j--){ num_10 *= 10; num_10 += num[j]; } a[num[i]] += num_10 + 1; // 减去 10^3(10^(i-1))个 0(0000~0999) a[0] -= p[i - 1]; } for (int i = 0;i <= 9;i++){ a[i] -= t[i]; } } int main(int argc, char **argv){ init(); ll A,B; cin >> A >> B; solve(A - 1); solve(B); for (int i = 0;i <= 9;i++){ cout << a[i] << ' '; } return 0; }
- 1
Information
- ID
- 171
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 8
- Tags
- # Submissions
- 47
- Accepted
- 9
- Uploaded By