您的位置:首页 > 其它

UVA1640 数位统计

2017-07-25 18:27 344 查看
参考博客:http://blog.csdn.net/u014800748/article/details/43956019

题目传送:https://vjudge.net/problem/UVA-1640

算法竞赛入门经典上的一道例题(P336)

这类问题的一般步骤都是先用f(n,d)计算出0~n中d数字出现的次数,那么答案就是f(b,d)-f(a-1,d)

下面程序中的注释为(1,2974)的第一层(未递归)解释,递归后同理

1-2974 拆分为1-2970  和 2971-2974

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
int a[15];
int b[15];

void copy(){
for(int i=0;i<10;i++)  a[i] = b[i];
memset(b,0,sizeof(b));
}

void cal(int n,int m){                //进入下一层,m*10
int x = n/10;       //除了末位以外的                     x=297
int y = n%10;          //末位                           y=4
int temp = x;
for(int i=1;i<=y;i++){         //计算小于10*x+1到10*x+y中个位数的个数           b[1-y]也就是(2971-2974)个位数
b[i] += m;
}
for(int i=0;i<10;i++){        //计算10*x-10到10*x-1中个位数的总个数            296 0-296 9 个位数个数每个都是296个
b[i] += m*x;
}
while(temp){
b[temp%10] += m*(y+1);     //10*x 到10*x+y非个位的个数         因为从0开始,所以*(y+1)就是非个位位数,当然还要乘m
temp/=10;
}
if(x) cal(x-1,m*10);           //递归到下一层
}

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

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: