给出一段区间a-b,统计这个区间内0-9出现的次数。

 
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
Input
两个数a,b(1 <= a <= b <= 10^18)
Output
输出共10行,分别是0-9出现的次数
Input示例
10 19
Output示例
1
11
1
1
1
1
1
1
1
1
思路:用记忆化搜索做,当计算0的数量是要特别注意
代码
 
#include<stdio.h>
#include<string.h>
#define ll long long
ll dis[12];//记录位数
ll lg,len;
ll s[25];//表示10的i次方
ll ans1[12];//记录答案
ll dp[25][15][2];
ll check(ll a){ //计算分解后的前a位的值
ll i=0;
ll ans=0;
for(i=0;i<=a;i++)
ans+=dis[i]*s[i];
return ans;
}
ll dfs(ll pos,ll lg,ll k){//计算1---9的数量
if(pos<0)
return 0;
ll num=lg?dis[pos]:9;
if(!lg&&dp[pos][k][lg]!=-1)//只有没有限制的时候才能用记忆化记录的结果
return dp[pos][k][lg];
ll i,j;
ll ans=0;
for(i=0;i<=num;i++){
if(i==k){//当i等于k时,当前有k的数量就要加上后面所有可能的数字的个数 (假设是542123,当前面已经遍历完542这三位时,
//当遍历到第四位且第四位为1时,1的数量就等于23中1数量+23)
if(lg&&i==num)//注意,前面的限制不一定能对后面的计算产生影响,要看当前的i是否可以继续产生限制。
ans=ans+check(pos-1)+1+dfs(pos-1,lg&&(i==num),k);//假设是542123这个数字,当取后三位是,一共有123+1种情况(0---123)
else
ans=ans+s[pos]+dfs(pos-1,lg&&(i==num),k);// 假设是542123,当前面已经遍历到541这三位时,
//当遍历到第四位且第四位为1时,1的数量就等于100中1数量+100)
}
else
ans+=dfs(pos-1,lg&&(i==num),k);
}
if(!lg)
dp[pos][k][lg]=ans;
return ans;
}
ll dfs1(ll pos,ll lg,ll lg1){//计算零的数量
if(pos<0)
return 0;
if(!lg&&!lg1&&dp[pos][0][lg]!=-1)//只有当没有限制并且前面有非零数字时,才能用到记忆化保存的数据
{
return dp[pos][0][lg];
}
ll num=lg?dis[pos]:9;
ll i,j;
ll ans=0;
//printf("%d\n",num);
//printf("pos=%d\n",dis[pos]);
for(i=0;i<=num;i++){
//prllf("c=%d %d\n",pos,i);
if(!lg1&&i==0){
if(lg&&i==num)//注意,前面的限制不一定能对后面的计算产生影响,要看当前的i是否可以继续产生限制,在这里连续卡了几次,以为自己考虑了,但是还是没有考虑,以后做题一定要注意。
{
//printf("a=%d %d %d\n",pos,i,cal(pos)+1);
ans+=check(pos-1)+1;//同上
}
else
{
ans+=s[pos];
//printf("b=%d\n",s[pos]);
} }
//printf("%d %d %d\n",pos,i,ans);
ans+=dfs1(pos-1,lg&&(i==num),lg1&&(i==0)); }
if(!lg&&!lg1)//记忆化没有限制并且前面有非零数字的情况
dp[pos][0][lg]=ans;
return ans;
}
int main(){
ll n,m;
len=0;
scanf("%lld%lld",&n,&m);
ll i;
s[0]=1;
for(i=1;i<=18;i++)
s[i]=s[i-1]*10;
n=n-1;
while(n){//分解数字
dis[len++]=n%10;
n=n/10;
}
memset(dp,-1,sizeof(dp));
ans1[0]=-dfs1(len-1,1,1);
//printf("%d\n",ans1[0]);
for(i=1;i<=9;i++){
ans1[i]=-dfs(len-1,1,i);
}
len=0;
while(m){
dis[len++]=m%10;
m=m/10;
}
ans1[0]+=dfs1(len-1,1,1);
printf("%lld\n",ans1[0]);
for(i=1;i<=9;i++){
ans1[i]+=dfs(len-1,1,i);
printf("%lld\n",ans1[i]);
} return 0;
}

  


51nod1042的更多相关文章

  1. 【51nod-1042】数字0-9的数量

    给出一段区间a-b,统计这个区间内0-9出现的次数.   比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. Inp ...

  2. 51nod1042(0-x出现次数&分治)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 题意:中文题诶- 思路:这道题和前面的51nod100 ...

随机推荐

  1. apply、call

    call(),apply() 1.每个函数都包含两个非继承而来的方法:call()和apply() 2.在特定的作用域内调用函数,等于设置函数体内的this对象,以扩充函数赖以运行的作用域 3.app ...

  2. php文件处理函数

    //basename的使用$path='test/abc.jpg'; echo basename($path);// echo '<br/>'; echo basename($path,' ...

  3. dsu on tree练习

    dsu on tree主要是处理一些有根树子树询问的操作, 作用与点分治和线段树合并类似. 一般无根树询问所有树链信息的直接就点分了, 有根树的话一般用线段树合并或dsu on tree, 线段树合并 ...

  4. python记录_day17 类与类之间的关系

    一.依赖关系 a类的对象是b类方法的参数 这种关系是我用着你,但你不属于我,比如公司和临时工的关系,是很弱的一种关系 class Zhiwu: def __init__(self,name,atk): ...

  5. 谈一谈HashMap类

    一.Java中的hashCode()和equals() 1. hashCode()的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode()是用来在散列存储结构中确定对 ...

  6. 【Oracle】【1】查询N分钟之前的数据

    --查询距离现在N分钟前的数据 1440:表示一天有1440分钟 SYSDATE - 10 :表示10天前 参考博客: 1,oracle 查询十分钟之前的数据 - 胡金水的博客 - CSDN博客 ht ...

  7. HashTable Queue Stack SortedList BitArray

    HashTable 由于是非泛型集合,因此存储进去的都是object类型,不管是键还是值. Hashtable不允许排序 key不允许重复 键不允许为null Queue和Queue<T> ...

  8. WCF开发实战系列一:创建第一个WCF服务 转

    转 http://www.cnblogs.com/poissonnotes/archive/2010/08/28/1811064.html 在这个实战中我们将使用DataContract,Servic ...

  9. python 小练习 6

    几种不同的方法写fibonacci 刚学Python不久的的C程序员: 01 def fib(n):#{ 02 if n<=2 : 03 return 1; 04 else: 05 return ...

  10. MYSQL--服务器的安装

    MYSQL--服务器的安装 学java已经好久了,但是还是没有学会安装数据库,这次重装系统后自己学了学,昨天晚上刚刚装好,卸载了,再装一次,就想着把它笔记下来.要不又忘了.. 1.删除你的服务.在cm ...