先讲poj2282:
题目很容易理解,但是做起来就有点苦难了
我是用递归,用例子3863这个例子来讲这个递归:
用递归需要把 f (3863) =f (386 ) + x 这个递归的式子理解清楚
去掉个位 3 :知道 3 8 6 这三个数字出现了4次( 0 1 2 3个位的数字可以是这四种情况)
然后就是处理个位的的数字 ,个位的数字出现了 386次,包括 0
每一层递归,需要把之前的 *10 ;第一层是 1
然后依次类推
注意!!! 0 这个数字的理解:避免首位的0 的出现
0 和其他数字不同,0 不能从最高位出现,而其他的数字可以从最高位出现,所以处理的时候,在同一位,0 出现的次数比其他的次数要少一次
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; int num_a[15],num_b[15]; int time; void deal(int num,int ans[]) { if(num<=0) return ; int t=num%10,temp=num/10; for(int i=1;i<=t;i++) ans[i]+=time; while(temp>0){ ans[temp%10]+=time*(t+1); temp/=10; } for(int i=0;i<=9;i++) ans[i]+=(num/10)*time; time*=10; deal(num/10-1,ans); return ; } int main() { int a,b; while(scanf("%d%d",&a,&b),a&&b) { memset(num_a,0,sizeof(num_a)); memset(num_b,0,sizeof(num_b)); if(a>b) swap(a,b); time=1; deal(a-1,num_a); time=1; deal(b,num_b); for(int i=0;i<=9;i++) printf("%d%c",num_b[i]-num_a[i],i==9?'\n':' '); } return 0; }
同理poj3286
#include<stdio.h> #include<iostream> using namespace std; long long num_1,num_2; long long ans; void deal(long long num,long long time) { if(num<0) return ; int t=num%10; long long temp=num/10; while(temp>0){ if(temp%10==0) ans+=time*(t+1); temp/=10; } ans+=(num/10)*time; time*=10; deal(num/10-1,time); return ; } int main() { long long m,n; while(scanf("%lld%lld",&m,&n),m!=-1&&m!=-1) { ans=0; deal(m-1,1); num_1=ans; ans=0; deal(n,1); num_2=ans; if(!m) num_2++; printf("%lld\n",num_2-num_1); } return 0; }