uva 11038 How Many O's? 组合计数

该博客探讨了UVA 11038编程问题,主要任务是在给定区间[n, m]内计算含有数字0的整数数量。博主提出了一种解决方案,通过定义函数f(n)来计算从0到n包含0的个数,并指出最终答案为f(m) - f(n - 1)。文章详细解释了如何根据每位数字是否为0来计算区间内的0个数,涉及位运算和组合数学的知识。" 8789524,1052120,PCA主成分分析详解与应用,"['数据分析', '数据降维', '机器学习', '统计学', '数据预处理']
摘要由CSDN通过智能技术生成

题意: 给两个数n,m 问在[n,m]里面的数,有多少个0

可以一位 一位地计算

设函数f(n)计算0~n包含0 的个数,答案就是f(m) - f(n - 1)

第i位如果不为0,那么这位为0的数将i位是前面的数和(0到999的组合数),比如111 的中间的0的个数就是 1 * 10  

如果为0,那么分为前部分为原来的数小于原数,第一部分0的数目为 后面部分数 + 1(0开始),第二部分则转化为第一种i位不为0 的情况

也就是说

n的第i位不为0,个数为n左边的数(高位)*10^i

n的第i位为0 ,个数为(n左边的数-1)*10^i  +(i位右边的数+1)


#include<cstdio>
#include <iostream>
#define ll long long
using namespace std;
ll count(ll n)
{
    if(n < 0) return 0;
    ll c = 1,r,k = 0,ans = 0;
    while(n > 9){
        r = n % 10; n /= 10;
        if(r) ans += n * c;
        else ans += (n - 1) * c + k + 1;
         k += r * c;
         c *= 10;
    }
    return ans;
}
int main()
{
    ll n, m;
    while(~scanf("%lld %lld",&m,&n),n >= 0){
        printf("%lld\n",count(n) - count(m - 1));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值