pat甲级1049(30分)c++

pat甲级1049(30分)c++

类型:数学

#include <iostream>
using namespace std;
/*
 * 题目大意:
 * 输入:
 * N
 * 输出:
 * 需要计算0到N的数字中包含1的个数
 */
int main() {
    //n是输入的数,now是当前位的数,a是now对应的数,例如十位时a=10,left是now左边的数,right是now右边的数,例如1001,now是十位时,now=0,left=10,right=1,ans是结果
    int n, left = 0, right = 0, a = 1, now = 1, ans = 0;
    scanf("%d", &n);
    //判断是否已经到最后一位
    while(n / a) {
        //对于left,now,right进行赋值
        left = n / (a * 10), now = n / a % 10, right = n % a;
        if(now == 0) ans += left * a;                       //如果now是0,则在该位上可能出现1的时候,左侧应为0到left-1,而这个时候右侧是a种可能,例如now是千位,右侧会有0到a-1种可能,所以会有left*a种
        else if(now == 1) ans += left * a + right + 1;      //如果now是1,则在该位上可能为1,在上一种可能上添加了右侧从0到right种可能
        else ans += (left + 1) * a;                         //如果now大于1,则为了让该位为1,左侧应为0到left,右侧应为0到a-1
        a = a * 10;                                         //进入下一位
    }
    //输出
    printf("%d", ans);
    return 0;
}

这道题很难想,源代码不是我的,添加上注释为了方便我理解,思路是计算每一位可能会出现1的次数累加,建议结合例子进行思考,至少我一开始很难理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值