pat1049 Counting Ones

题意:给一个数N,计算从0到N的所有数中数位1的个数,N\leq 2^{30}

思路:数位dp,定义dp[i][j]表示从0到以i为首位长度为j后位全是0的区间有多少数位1。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;

const int MAX_N = 10;
char s[MAX_N];
ll dp[10][35], len;
ll ans;

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    dp[0][0] = 0;
    for (int i = 1; i <= 10; i++) {
        for (int j = 0; j <= 9; j++) {
            if (j == 0) {
                for (int k = i-1; k >= 1; k--) {
                    dp[j][i] += dp[9][k];
                }
            } else {
                if (j > 1) dp[j][i] = dp[j-1][i] + dp[0][i] + (j-1==1?(ll)(pow(10, i-1)-1):0);
                else dp[j][i] = dp[0][i] + 1;
            }
        }
    }
    scanf("%s", s);
    len = strlen(s); ans = 0;
    for (int i = 0; i < len; i++) {
        if (s[i]-'0' == 0) continue;
        ans += dp[s[i]-'0'][len-i];
        if (s[i]-'0'==1) {
            ans += (ll)atoi(s+i+1);
        }
    }
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/csx0987/article/details/82494915