51Nod 1009 1042 數位DP

題目鏈接

給定一個十進制正整數N,寫下從1開始,到N的所有正數,計算出其中出現所有1的個數。
例如:n = 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。
Input
輸入N(1 <= N <= 10^9)
Output
輸出包含1的個數
Input示例
12
Output示例
5

思路:
初學數位dp第二題。
解釋: 假設數字是 ZYAX,從個位開始向最高位開始枚舉,對每一位出現的1加和,就是答案。
現在枚舉到A,pos(2)位。left = ZYA , mul = pow(10,pos-1).

如果A==0 那麼前面不能出現0,高位的情況就是 left/10 (從1到ZY),低位的情況是 mul;低位與高位相乘就是該位的可能出現1的次數。
如果A>1,高位可以出現0,高位的情況就是 left/10+1 (從0到ZY),低位的情況是 mul;
如果A==1 時候,分兩個
第一:高位從0到ZY-1,這時候低位的情況是mul
第二,高位是ZY時候,低位就是X

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long ll;

int main()
{
    int n;
    int x;
    int left;
    int mul;
    ll ans;

    cin>>n;
    left = n;
    mul = 1;
    ans = 0;
    while ( left ) {
        x = left%10;
        if ( x==0 ) {
            ans += (left/10)*mul;
        } else if ( x==1 ) {
            ans += (left/10)*mul;
            ans += n-left*mul+1 ;
        } else {
            ans += (left/10+1)*mul;
        }
        mul *= 10;
        left /= 10;
    //cout<<ans<<endl;
    }
    cout<<ans<<endl;
    return 0;
}

1042 是進階版

就是將1換成i(0-9);
在0的時候有一個問題,會多加上高位爲0的情況,這時候需要減掉。

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll judge( ll num,int target ) {
    ll n = num;
    ll x;
    ll left;
    ll mul;
    ll ans;

    left = num;
    mul = 1;
    ans = 0;
    //19
    while ( left ) {
        x = left%10;
        if ( x<target ) {
            ans += (left/10)*mul;
        } else if ( x==target ) {
            ans += (left/10)*mul; 
            ans += n-left*mul+1 ;
        } else {
            ans += (left/10+1)*mul;
        }
        mul *= 10;
        left /= 10;
    }
    if ( target==0 ) {
        ll m=10;
        ll nx = num/10;
        while ( nx ) {
            ans -= m;
            m *= 10;
            nx /=10;
        }
    }
    return ans;
}
int main()
{
    ll a,b;
    cin>>a>>b;
    for ( int i=0; i<10; i++ )
        cout<<judge(b,i)-judge(a-1,i)<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章