解法一:数学
依次统计各个位置上“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;}
