数字计数问题(算法实验)
来源:互联网 发布:行业经济数据对比 编辑:程序博客网 时间:2024/04/29 06:33
数字计数问题
时间限制:3000 ms | 内存限制:65535 KB
描述
一本书的页码从自然数1开始顺序编码到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6页用数字6表示,而不是06或者006等。数字计数问题要求对给定书的总也码n,分别计算出0,1,…,9总共出现的次数
输入
给定的页码n (0<n<10000000)
输出
分别输出0,1,…,9出现的总次数
样例输入
99
样例输出
9 20 20 20 20 20 20 20 20 20
要求
不能直接从1循环到n,对每个数字计算0~9出现的次数。
/*算法实验题,我觉得蛮难的蛮麻烦的=_=(对于算法课来说),或者是我太水.>_<,想去网上看人家怎么破才比较简单,没找到,或者我搜索能力也是很水=_=dp[i][j][k] ,表示长度为 i , 以 j 开头 , k 用的次数转移 dp[i][j][k] = 求和(dp[i-1][u][k]) 0 <= u <= 9 dp[i][j][j] += 10^(i-1) ;因为不能有前导 0 ,所以我们开了 hehe数组hehe[i][j] 表示长度为 i-1 的所以数 , j 用的次数 然后对于 n , == 不好解释,取个例子 n = 2345 先把 n 的各个位拿出来对于 0 开头的,直接取 hehe[3][]对于 1 开头的,都可以取了 就是 dp[4][1][]对于 2 开头的,2 能去 345 (2345%1000) 个然后 就是 2 开头下面的 2X1X2X3 x1 = 0 ,在 hehe 里面已经算了 x1=1,2都可以取 对于 x1 = 3 , 3 能取 45(2345%100) 个 然后对于 23X2X3 ....一直这样下去ps: 测试了很多数据是对的,没有oj可以交,所以不能保证所有的都是对的,
助教应该看不到的吧,hehe
by 20120125*///E
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<ctime>
#define maxn 110
#define LL long long
using namespace std ;
LL dp[12][12][12] ,hehe[12][12] ;
int ans[12] ;
int get( int n )
{
int ans = 1 ;
for( int i = 1 ; i <= n ;i++ )
ans *= 10 ;
return ans ;
}
void init()
{
int i ,j, k ,u ;
memset(dp,0,sizeof(dp)) ;
memset(hehe,0,sizeof(hehe));
for( i = 0 ; i < 10 ;i++ ){
dp[1][i][i] = 1 ;
for( j = 0 ; j < 10 ;j++ )
hehe[2][j] = 1 ;
}
for( i = 2 ; i <= 10 ;i++ )
{
for( j = 0 ; j < 10 ;j++ )
{
for( k = 0 ; k < 10 ;k++ )
for( u = 0 ; u < 10 ;u++ )
dp[i][j][k] += dp[i-1][u][k] ;
dp[i][j][j] += get(i-1) ;
}
for( j = 0 ; j < 10 ;j++ )
hehe[i+1][j] = hehe[i][j] ;
for( j = 1 ; j < 10 ;j++ ){
for( u = 0 ; u < 10 ;u++ )
hehe[i+1][u] += dp[i][j][u] ;
}
}
}
int find( int u , int n )
{
int i , t = 1 ;
for( i = 1 ; i < u ;i++)
t *= 10 ;
return n%t ;
}
void getans( int n )
{
int bit[19] ,i,k , m = n,j ;
memset(ans,0,sizeof(ans)) ;
k = 1 ;
while(n)
{
bit[k++] = n%10 ;
n /= 10 ;
}
for( i = 0 ; i < 10 ;i++ )
ans[i] = hehe[k-1][i] ;
for( i = k-1 ; i >= 1 ;i-- )
{
if(i==k-1) j =1 ;
else j = 0 ;
for( ; j < bit[i] ;j++)
for( k = 0 ; k < 10 ;k++)
ans[k] += dp[i][j][k] ;
ans[bit[i]] += find(i,m)+1 ;
// for( j = 0 ; j < 10 ;j++)
// ans[j] += hehe[i][j] ;
}
}
void zhe( int n )//暴力
{
memset(ans,0,sizeof(ans)) ;
for( int i = 0 ; i<= n ;i++ )
{
int m = i ;
while(m)
{
ans[m%10]++ ;
m /= 10 ;
}
}
}
int main()
{
int i,j ,n ;
//freopen("in.txt","r",stdin) ;
int tt=clock() ;
init();
while( scanf("%d",&n) != EOF )
{
getans(n) ;
cout << ans[0] ;
for( i = 1 ; i < 10 ;i++ )
printf(" %d",ans[i]) ;
puts("") ;
}
cout << "time: " << clock()-tt << endl;
return 0 ;
}
0 0
- 数字计数问题(算法实验)
- 正整数中数字1的计数问题 - 简单算法(上)
- 数字组合(背包计数)
- Algorithm学习笔记 --- 计数问题(分治算法)
- 第一次实验--NPC问题(回溯算法)
- 算法实验:格雷码问题
- 计数问题(一)
- 计数问题(二)
- 计数问题(/C++)
- 【算法】数字三角形问题
- 算法 数字排列问题
- 算法 数字三角形问题
- 正整数中数字1的计数问题 - 采用分治法快速计算f(n)(下)
- 《栈的计数》问题的算法分析
- 哈工大 基础算法 1001 计数问题
- bzoj1833 [ZJOI2010]count 数字计数(数位)
- count 数字计数 (数位dp)
- 计数算法(Counting sort )
- v4l2 camera测试程序
- ios xmpp 发送语音图片解决方案
- leetcode第一刷_Longest Valid Parentheses
- 这一年我们二十七八岁
- 用IIS搭建WEB服务器
- 数字计数问题(算法实验)
- 深度遍历二叉树
- 转: Java:重写equals()和hashCode()
- 改变 项目在系统上显示的名称
- 算法导论笔记(1)
- highcharts做图形报表如何去掉highcharts.com
- java.next:功能编码风格!
- ZendStudio中设置SVN:ignore
- mina 框架java服务端的搭建和通信。