The Counting Problem poj2282

/************************************************************************/
/* 

递归问题:
给定一个区间,求其中所有0~9数字总计出现次数

思路:
设f(a),f(b)为各自从1开始到a,b中所有0~9数字总计出现次数。
则ans=f(b)-f(a-1);递归的话就是建立f(k)和f(10*k+x)的关系.

对于一个大数,先处理到末尾为0,然后再认为是从0开始10个10个数,数到这个数。
例如,f(2984)就先从2981数到2984(2,9,8各出现4次,1,2,3,4一次)然后
f(2980)可以和f(298)建立递推(实际的时候用f(297)更好一点)。
注意这里需要建立一个“乘子”,一开始为1,每次递推一层就*10,然后累加到0-9的记录上。

换句话说
逐位计算每个数字出现的个数
2984  先计算个位上的  2981 2982...2984    298各出现4次,1 2 3 4各一次
然后可以得知从1变化到2980 各位都各自变化了298次,对于2980 0的计算已经包含进来了,所以不用计算而298出现次数都再加一
然后个位上的不用管,看十位上的变为297 这时候乘子要变为之前的10倍
(若为10,那么从1到10每位各出现了1次,1再多一次,若做类似变化,10->1的时候会认为各位再多变了一次)
所以不用298
*/
/************************************************************************/

#include <iostream>
#include <string>
using namespace std;

int a,b;
int ansa[10],ansb[10];

void count_digits(int s,int *ans,int times)//
{
    int i,p,m;
	if(s<=0) return;
	m=s%10;
	p=s/10;
	for(i=1;i<=m;i++)
		ans[i]+=times;//
	while(p)
	{
		ans[ p%10 ]+=(m+1)*times;
		p/=10;
	}
	for(i=0;i<10;i++)
		ans[i]+=times*(s/10);
	count_digits((s/10)-1   ,ans,times*10);

}

int main()
{
    int i,j;
while(scanf("%d%d",&a,&b),a + b)
{
   memset(ansb,0,sizeof(ansb));
   memset(ansa,0,sizeof(ansa));
   if (a >= b)
   {
      swap(a,b);
   }
   a --;
   if (b > a)
   {
      count_digits(b,ansb,1);
      count_digits(a,ansa,1);
   }
   for(i=0;i<10;i++)
   {
       printf("%d%c",ansb[i]-ansa[i],i==9?'\n':' ');
   }

}

return 0;
}

The Counting Problem poj2282

时间: 2024-08-15 03:41:03

The Counting Problem poj2282的相关文章

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的区间逐步统计.

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

POJ 2282 The Counting Problem,组合数学

POJ 2282 The Counting Problem,组合数学 ACM 题目地址:POJ 2282 题意: 给出俩数n,m,求从n~m中0~9分别出现的次数. 分析: 组合数学. 只要能快速算出0~n中各个数的出现次数就能解决问题了. 要把数拆开来看,比如3456=3000+400+50+6. 然后就只要考虑后面都是0的数就行了. 0~3000中,我们要分为两部分来考虑: 在第一位中,0\1\2都出现了1000次. 假设不管第一位,后面那些位数出现0~9的几率是均等的(先不考虑前导0).那

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

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

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

SWJTU2017-6月月赛 G-A Easy Counting Problem[数论][乘法逆元]

传送门:http://www.swjtuoj.cn/problem/2397/ 题解:产生交点的条件为4个点构成四边形对角线产生交点,最大解当产生的交点位置完全不相同时存在.答案为$C_{\text{n}}^4$ 计算组合数时需要使用乘法逆元 代码: 1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #include<iostream> 4

POJ 2282 Counting Problem

http://poj.org/problem?id=2282 题意:问[a,b]内 数字[0~9]分别出现多少次? a,b<=1e9. 数位DP dp[len][sta]:当前长度为len 数字y的初始状态为sta时,数字y共出现了多少次? 枚举当前位 如果为i!=num ,len-1位y的初始状态为sta 如果i==num ,len-1位y的初始状态为sta+1当前位<0 则返回y的出现次数 #include <iostream> #include <cstring>