51nod 1009 数字1的数量(数位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



题目简单易懂就不多作解释了,下面说一下大体思路
把每个数拆分 用123来举例

个位:出现了13次1(1 11 21···91,101 111 121)
十位:20次 (10-19 110-119)

百位:24次(100-123)
细心的聚聚们可能已经发现了规律

把当前位数分为三类:
如果小于1:则出现1的次数只与更高位有关

如果等于1:和更高位,低位都有关
如果大于1:   只与更高位有关

这里的高位与低位不是指那一位,而是当前位之前的数和之后的数
举个例子:1234

拿百位来说 高位是1 而低位是34不是3!!!!
下面贴上蒟蒻的代码

#include<bits/stdc++.h>
using namespace std;
int N,t1,t2,t3,num;
int main()
{
    ios::sync_with_stdio(false);
    cin>>N;
    int temp=1;
    while(N/temp!=0)
    {
        t1=N/(temp*10);//计算更高位
        t2=(N/temp)%10;//计算当前位置
        t3=N-(N/temp)*temp;//计算低位
        if(t2==1)
        {
            num=num+t1*temp+t3+1;
        }
        else if(t2>1)
        {
           num=num+(t1+1)*temp;
        }
        else if(t2<1)
        {
            num=num+t1*temp;
        }
        temp=temp*10;
    }
        cout<<num<<endl;
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值