开始想用dp[i][j]来记录第i位j开头含有49的数的个数 但是init后并不知道如何进行cal
想了想可以用不要62的思想 当作不要49来做 然后减一下 就好
看网上的代码 不要62和这道题用的dp方法和cal都与我用的有很大不同
做完入门水题就去学习一下那种很正规的方法~
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> #include<queue> using namespace std; /// 含有49 为吉利数 long long int dp[50][11]; /// dp[i][j] i为第i位 j为首数字 dp含义有多少吉利数 /// 可以化作 不要62 类型来做 最后减去就可以 long long int n; void init(){ memset(dp,0,sizeof(dp)); for(int i=0;i<=9;i++) dp[1][i]=1; for(int i=1; i<=45;i++) { for(int j=0;j<=9;j++) { for(int k=0;k<=9;k++) { if(!(j==4&&k==9)) { dp[i][j]+=dp[i-1][k]; } } } } } long long int cal(long long int x) { long long int sum=x; int z=0; int A[50]; while(x>0) { z++; A[z]=x%10; x/=10; } A[z+1]=0; long long int ans=0; for(int i=z;i>=1;i--) { for(int j=0;j<A[i];j++) { if(!(A[i+1]==4&&j==9)) ans+=dp[i][j]; } if(A[i+1]==4&&A[i]==9) break; } return sum-ans; } int main(){ init(); int t; scanf("%d",&t); while(t--) { scanf("%I64d",&n); printf("%I64d\n",cal(n+1)); } }
时间: 2024-10-13 16:08:13