給定一個十進制正整數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;
}