解法一:数学
依次统计各个位置上“1”出现的次数,注意分情况讨论。先写一个暴力解法用于验证算法的正确性。
#include <bits/stdc++.h>
using namespace std;
long long force(long long n) {
long long cnt = 0;
string str;
for (long long i = 1; i <= n; ++i) {
str = to_string(i);
for (auto ch:str) {
if (ch == '1') {
++cnt;
}
}
}
return cnt;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
// cout << force(N) << endl;
long long cnt = 0;
long long x = 1, min, max;
long long index = 1;
long long tmp;
while (x <= N) {
min = x;
max = x * 2 - 1;
if (N >= max) {
cnt += ((N - max) / (x * 10) + 1) * x;
tmp = N % (x * 10);
if (tmp >= min && tmp < max) {
cnt += tmp - min + 1;
}
} else {
cnt += N - min + 1;
}
x *= 10;
}
cout << cnt << endl;
}