UVa1640 - The Counting Problem(数位统计)

题意:

  统计两个整数a,b之间各个数字(0~9)出现的次数,如1024和1032,他们之间的数字有1024 1025 1026 1027 1028 1029 1030 1031 1032 总共有10个0,10个1,3个3等等。

分析:

  因为前导0的干扰,为了计算方便暂时都先计算在内,之后再减;

  如果是0~199,那么百位上的0和1各出现一次,s剩下的就是两个00~99,总共两百个二位数,而每个数出现的次数都一样,都是2*(99-00+1)/10;

  那么任意的数都可以分解成类似的数字,如3426,则可以分成0000~2999,3000~3399,3400~3419,3420~3426几个部分各自计算,再求和按位减去前导0的个数。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
void Cal(char *s,int *num){
    int i,j,k,n,t,m=atoi(s);
    n=strlen(s);
    for(i=k=1;i<n;i++)
        k*=10,num[0]-=k;
    for(i=0;i<n;i++,k/=10){
        for(j=0;j<s[i]-'0';j++)
            num[j]+=k;
        for(t=0;t<10;t++)
            num[t]+=k/10*(n-i-1)*j;
        if(i+1<n) num[j]+=atoi(s+i+1);
        num[j]++;
    }
}
int main()
{
    char s[22];
    int i,n,m,a[11]={0},b[11]={0};
    for(;scanf("%d%d",&n,&m),m+n;){
        if(n>m) swap(n,m);
        memset(a,0,sizeof(a));
        sprintf(s,"%d",n-1);
        Cal(s,a);
        memset(b,0,sizeof(b));
        sprintf(s,"%d",m);
        Cal(s,b);
        for(i=0;i<9;i++)
            printf("%d ",b[i]-a[i]);
        printf("%d\n",b[9]-a[9]);
    }
}
时间: 2024-10-20 14:51:31

UVa1640 - The Counting Problem(数位统计)的相关文章

poj2282 The Counting Problem 数位dp

题意:给两个数l,r,求[l,r]区间内这么多数包含多少个"0" "1" "2"..."9". 比如[1 10] 除了"1"有2个,其余数字均只有1个. 思路:数的范围为1e8,又是数的统计,一看就是数位dp.设dp[ i ] [ pos ] [ cnt ]为当前考虑数字为i,且当前考虑pos位,之前的位已经 有cnt个数字i,之后(pos+1)位与之前数位组合含数字i的个数.那么除了数字"0&q

UVa 1640 The Counting Problem (数位DP)

题目 题目大意 给出\(a\).\(b\), 统计\(a\)和\(b\)(包含\(a\)和\(b\))之间的整数中, 数字\(0, 1, 2, 3, 4, 5, 6, 7, 8, 9\)分别出现了多少次.\(1 ≤ a, b ≤ 10^8\).注意, \(a\)有可能大于\(b\). 题解 设\(f_d(n)\)表示\(0 \cdots n\)中数字\(d\)出现的个数, 则求的是\(f_d(a) - f_d(b - 1)\). 暴力显然是会\(TLE\)的, 我们可以分段来求.例如我们要求\(

UVA 1640 The Counting Problem UVA1640 求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数。

/** 题目:UVA 1640 The Counting Problem UVA1640 链接:https://vjudge.net/problem/UVA-1640 题意:求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数. 思路:数位dp: dp[leadzero][i][j][k]表示前面是否选过非0数,即i长度之后可以第一个出现0,而不是前导0,长度为i,前面出现j,k次,j出现的次数. */ #include<iostream> #include<cstri

UVALive3261 UVA1640 POJ2282 HDU1663 ZOJ2392 The Counting Problem

Regionals 2004 >> Asia - Shanghai 问题链接:UVALive3261 UVA1640 POJ2282 HDU1663 ZOJ2392 The Counting Problem. 问题简述:输入m和n,计算m到n(包括m和n)之间各个数中包含多少个0-9数字. 问题分析:先分别计算0到m-1和0到n之间数的数字个数,结果=0到n之间数的数字个数-0到m-1之间数的数字个数.计算0到n之间数的数字个数时,先考虑1位数.2位数.......,在小于n的区间逐步统计.

[ACM] ural 1057 Amount of degrees (数位统计)

1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK different integer degrees of B. Example. Let X=15, Y=20, K=2, B=2. By this exampl

UVA 1640(数位统计)

The Counting Problem Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu SubmitStatus Description Given two integers a and b, we write the numbers between a and b, inclusive, in a list. Your task is to calculate the number of occur

POJ 2282-The Counting Problem(组合数学_区间计数)

The Counting Problem Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2282 Appoint description:  System Crawler  (2015-04-15) Description Given two integers a and b, we write the numbers between

POJ2282 The Counting Problem

题意 Language:DefaultEspa?ol The Counting Problem Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 5070 Accepted: 2590 Description Given two integers a and b, we write the numbers between a and b, inclusive, in a list. Your task is to calcula

HDOJ 1663 The Counting Problem 打表

先打出0~8位数,分别可以被整十/百/千/万...整除时 , 各个数字出现了几次的表 先把每要查询的数字的每一位在表里查询得到一个结果 但是这样是不全面的,考虑这样的情况: 例如2345这样的数 234* 这种情况下 4出现了5次 23**这种情况下3出现了45次 2***中2出现了345次等.....从后往前扫一遍即可 其中0的情况比较特殊,简单的扫一遍会漏掉很多可能 比如 5050时: 500*的情况下,第2个0就没有考虑到,所以还要进行一次补0的操作. 排除首位从前往后扫,遇到每一个不为0