标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 15072 Accepted Submission(s): 5441
题意:求1~n闭区间内含有“49”的数的个数
题解:
dp[i][2] 长度为i 含有“49”的个数
dp[i][1] 长度为i 不含有“49”但是高位为“9”的个数
dp[i][0] 长度为i 不含有“49”的个数
数组 a[i] 从低位到高位存储 n 的每一位数字。
dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; //考虑第i位为“4” i-1位为“9”
dp[i][1]=dp[i-1][0];
dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
对于n处理之前为什么要自增1
因为题目要求处理的是闭区间 可能自增1当作开区间处理
http://www.cnblogs.com/liuxueyang/archive/2013/04/14/3020032.html
1 /****************************** 2 code by drizzle 3 blog: www.cnblogs.com/hsd-/ 4 ^ ^ ^ ^ 5 O O 6 ******************************/ 7 //#include<bits/stdc++.h> 8 #include<iostream> 9 #include<cstring> 10 #include<cstdio> 11 #include<map> 12 #include<algorithm> 13 #include<queue> 14 #define ll __int64 15 using namespace std; 16 int t; 17 ll n; 18 ll a[65]; 19 ll dp[65][5]; 20 void init() 21 { 22 dp[0][0]=1; 23 for(int i=1; i<=22; i++) 24 { 25 dp[i][0]=10*dp[i-1][0]-dp[i-1][1]; 26 dp[i][1]=dp[i-1][0]; 27 dp[i][2]=10*dp[i-1][2]+dp[i-1][1]; 28 } 29 } 30 int main() 31 { 32 init(); 33 while(scanf("%d",&t)!=EOF) 34 { 35 for(int i=1; i<=t; i++) 36 { 37 scanf("%I64d",&n); 38 memset(a,0,sizeof(a)); 39 int len=1; 40 n++; 41 while(n) 42 { 43 a[len]=n%10; 44 n=n/10; 45 len++; 46 } 47 int flag=0; 48 int last=0; 49 ll ans=0; 50 for(int j=len; j>=1; j--) 51 { 52 ans+=dp[j-1][2]*a[j]; 53 if(flag) 54 ans+=dp[j-1][0]*a[j]; 55 if(!flag&&a[j]>4) 56 ans+=dp[j-1][1]; 57 if(last==4&&a[j]==9) 58 flag=1; 59 last=a[j]; 60 } 61 printf("%I64d\n",ans); 62 } 63 } 64 return 0; 65 }
标签:
原文地址:http://www.cnblogs.com/hsd-/p/5754342.html