zoukankan      html  css  js  c++  java
  • BZOJ 1833 ZJOI2010 count 数字计数 数位DP

    题目大意:求[a,b]间全部的整数中0~9每一个数字出现了几次

    令f[i]为i位数(算前导零)中每一个数出现的次数(一定是同样的,所以仅仅记录一个即可了)

    有f[i]=f[i-1]*10+10^(i-1)

    然后照例十进制拆分

    当中计算[0,999...9]的时候要从1~9枚举最高位,然后其余位调用f[i-1]就可以

    剩余部分已知位直接乘,未知位调用f[i]

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    ll ans[10],f[20];
    inline void Resolve(ll x,ll pos)
    {
    	while(x)
    		ans[x%10]+=pos,x/=10;
    }
    void Digital_DP(ll x,int flag)
    {
    	int i,j;
    	ll pos,now;
    	for(i=1,pos=10;pos<x;++i,pos*=10)
    	{
    		for(j=0;j<=9;j++)
    			ans[j]+=f[i-1]*9*flag;
    		for(j=1;j<=9;j++)
    			ans[j]+=pos/10*flag;
    	}
    	now=pos/=10;--i;
    	while(now<x)
    	{
    		while(now+pos<=x)
    		{
    			ll temp=now/pos;
    			Resolve(temp,pos*flag);
    			for(j=0;j<=9;j++)
    				ans[j]+=f[i]*flag;
    			now+=pos;
    		}
    		pos/=10;--i;
    	}
    }
    int main()
    {
    	int i;
    	ll a,b,pos;
    	f[1]=1;
    	for(i=2,pos=10;i<=12;i++,pos*=10)
    		f[i]=f[i-1]*10+pos;
    	cin>>a>>b;
    	Digital_DP(b+1,1);
    	Digital_DP(a,-1);
    	for(i=0;i<=9;i++)
    		printf("%lld%c",ans[i],i==9?'
    ':' ');
    }
    


  • 相关阅读:
    博客
    NFS服务配置
    LAMP环境搭建与配置
    Linux系统管理技巧(下)
    Linux系统管理技巧(上)
    LVM
    安装RPM包或源码包
    Linux第四章 文件和目录管理
    MySQL主从配置 : 配置主和从(一) 配置主
    MySQL主从配置:主从介绍
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5213073.html
Copyright © 2011-2022 走看看