您的位置:首页 > 其它

51Nod 1009 1042 数位DP

2018-03-31 17:52 316 查看
题目链接

给定一个十进制正整数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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp