题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009
输入N(1 <= N <= 10^9)
输出包含1的个数
12
5
解析:
假设N,我们要计算百位上出现1的次数,将由三部分决定:百位上的数字,百位以上的数字,百位一下的数字。
如果百位上的数字为0,则百位上出现1的次数仅由更高位决定,比如12013,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,共1200个。等于更高位数字乘以当前位数,即12 * 100。
如果百位上的数字大于1,则百位上出现1的次数仅由更高位决定,比如12213,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,12100~12199共1300个。等于更高位数字加1乘以当前位数,即(12 + 1)*100。
如果百位上的数字为1,则百位上出现1的次数不仅受更高位影响,还受低位影响。例如12113,受高位影响出现1的情况:100~199,1100~1199,2100~2199,…,11100~11199,共1200个,但它还受低位影响,出现1的情况是12100~12113,共114个,等于低位数字113+1。
借鉴大牛博客:http://www.cnblogs.com/jy02414216/archive/2011/03/09/1977724.html
代码如下:
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cctype>
#define N 509
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long LL;
const int mod = 1000000009;
const double eps = 1e-8;
int solve(int n)
{
int i = 1, l, cur, r, ans = 0;
while(n / i != 0)
{
cur = (n / i) % 10;
l = n / (i * 10);
r = n - (n / i) * i;
if(cur == 0) ans += l * i;
else if(cur == 1) ans += l * i + r + 1;
else ans += (l + 1) * i;
i *= 10;
}
return ans;
}
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", solve(n));
return 0;
}