//http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3930
//Problem description:
Space Elevator
China is building a space elevator, which will allow the launching probes and satellites to a much
Input
The input contains several test cases. Each test case consists of a single line containing an integer
Output
For each test case, print a line containing a single integer indicating the number assigned to the• 1 ≤ N ≤ 10^18
666
//解题思路:一个数位dp的题,dp[i][0]记录不含4和13且第一位数字不为3的个数,dp[i][1]记录不含4和13但第一位数字为3的个数,dp[i][2]记录里面含有4或13,或都有的个数,最后状态转移如下所示:
dp[i][0]=7*(dp[i-1][0]+dp[i-1][1])+dp[i-1][0];
dp[i][1]=dp[i-1][0]+dp[i-1][1];
dp[i][2]=dp[i-1][1]*2+dp[i-1][0]+10*dp[i-1][2];
这题还有一个注意的地方就是long long 的范围不够用了,要用unsigned long long;
//Code as follows:
#include<stdio.h> #include<string.h> unsigned long long dp[22][3],num[22]; void init() { int i; memset(dp,0,sizeof(dp)); dp[0][0]=1; for(i=1;i<20;i++) { dp[i][0]=7*(dp[i-1][0]+dp[i-1][1])+dp[i-1][0]; dp[i][1]=dp[i-1][0]+dp[i-1][1]; dp[i][2]=dp[i-1][1]*2+dp[i-1][0]+10*dp[i-1][2]; } num[0]=1; for(i=1;i<20;i++) num[i]=num[i-1]*10; } unsigned long long get(unsigned long long n) { int i,flag=0; unsigned long long p[22],pnum[22],sum=0; memset(pnum,0,sizeof(pnum)); i=0; while(n) { p[++i]=n%10; pnum[i]=pnum[i-1]+num[i-1]*p[i]; n/=10; } for(;i;i--) { sum+=dp[i-1][2]*p[i]; if(p[i]==1) flag=1; else if(p[i]>1) { if(i>1) sum+=dp[i-1][1]; if(p[i]==3) { if(flag) { sum+=pnum[i-1]+1; break; } } else if(p[i]>3) { if(flag)sum+=dp[i][1]; if(p[i]==4) { sum+=pnum[i-1]+1; break; } else { sum+=dp[i-1][1]; sum+=dp[i-1][0]; } } flag=0; } else flag=0; } return sum; } unsigned long long find(unsigned long long n) { unsigned long long tem,mid,start=0,end=num[19]+1,t; while(start<=end) { t=start%2+end%2; mid=start/2+end/2+t/2; tem=mid-get(mid); if(end==mid)break; if(tem>=n) end=mid; else start=mid+1; } return end; } int main() { unsigned long long n; //freopen("out.out","w",stdout); init(); while(scanf("%llu",&n)!=EOF) printf("%llu\n",find(n)); return 0; }