您的位置:首页 > Web前端 > Node.js

数位DP - 数字1的数量

2017-05-20 12:03 381 查看
1009 数字1的数量

基准时间限制:1 秒 空间限制:131072 KB 分值: 5难度:1级算法题

给定一个十进制正整数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[i]表示 1~10^(i-1) 内数字1 的个数

for(int i=1;i<15;++i)
{
dp[i]=dp[i-1]*10+po;
po*=10;
}
然后对于每一位数字,要考虑数字与1的关系。

好比141,到第三个1的时候,实际上已经算出了1~41的1的数量,那我把这个数量想象成是在100~141里面除开开头的1的数量,加上42个开头的1,这个还没算。然后还有的就是1~99的1的数量。
if(digit>1) ans+=digit*dp[i-1]+po;
else if(digit==1) ans+=dp[i-1]+tail+1;
这里的ans要不断累加,表示每一位上1的数字。

code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define LL long long

using namespace std;

LL dp[15];

void init()
{
memset(dp,0,sizeof(dp));
LL po=1;
for(int i=1; i<15; ++i)
{
dp[i]=dp[i-1]*10+po;
po*=10;
}
}

int main()
{
LL x;
init();
while(scanf("%lld",&x)!=EOF)
{
LL po=1,tail=0,ans=0;
int digit,i=1;
while(x)
{
digit=x%10;
x/=10;
if(digit>1) ans+=digit*dp[i-1]+po;
else if(digit==1) ans+=dp[i-1]+tail+1;
++i;
tail+=digit*po;
po*=10;
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息