码迷,mamicode.com
首页 > 其他好文 > 详细

BNU 26351 Space Elevator 数位dp

时间:2015-08-14 19:13:26      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

Problem E
Space Elevator
China is building a space elevator, which will allow the launching probes and satellites to a much
lower cost, enabling not only scienti?c research projects but also space tourism.
However, the Chinese are very superstitious, and therefore have a very especial care with the
numbering of ?oors in the elevator: they do not use any number containing the digit “4” or the
sequence of digits “13”. Thus, they do not use the fourth ?oor or the ?oor 13 or the ?oor 134 nor the
?oor 113, but use the ?oor 103. Thus, the ?rst ?oors are numbered 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 15,
16, . . .
As the space elevator has many levels, and levels must be numbered, the Chinese asked you to
write a program that, given the level, indicates which number should be assigned to it.
Input
The input contains several test cases. Each test case consists of a single line containing an integer
N which indicates the ?oor whose number should be determined.
Output
For each test case, print a line containing a single integer indicating the number assigned to the
N-th ?oor.
Restrictions
? 1 ≤ N ≤ 1018
Examples
Sample input
1
4
11
12
440
Sample output
1
5
12
15

666

题意,从小到大,去掉有4和13的数,要求第n位数是多少。

用dp[l][t]表示长为l位的,t = 0表示没有限制 t =1 表示最后一位是1,t = 2表示结束为4或者是13的个数。则任何一个数,都可以很快转化成dp[l][t]来求解,如果是同一位数,很对应的那么数开始计数,否则从9开始计数,记忆化搜索就可以了。得到了个数,可以用个二分的方法,找到答案就可以了。不过这题有个坑,如果是10^18这个数,就是用long long是会爆的,要用unsinged long long,总的复杂度为log(n0) * log(n)

#define N 100
#define ll unsigned long long
#define INF 18223372036854775800
ll pri[N],dp[N][3];
ll get(ll d,ll t){
    if(d==2||t==4||(d==1&&t==3))return 2ll;
    if(t==1)return 1ll;
    return 0ll;
}
ll dfs(ll pos,ll d,ll flag){
    if(pos==0)return d==2;
    if(!flag&&dp[pos][d]!=-1)return dp[pos][d];
    ll u=flag?pri[pos]:9,ans=0;
    for(ll i=0;i<=u;i++)
    ans+=dfs(pos-1,get(d,i),flag&&(i==u));
    return flag?ans:dp[pos][d]=ans;
}
ll solve(ll x){
    ll cnt=0,tx = x;
    while(x){
        pri[++cnt]=x%10;
        x/=10;
    }
    ll temp = tx - dfs(cnt,0,1);
    return temp;
}
ll getans(ll n){
    ll l = 1,r = INF,mid;
    while(l < r - 1){
        mid = l + (r - l)/2;
        ll x = solve(mid);
        if(x < n) l = mid;
        else r = mid;
    }
    if(solve(l) == n) return l;
    if(solve(r) == n) return r;

    return 0;
}
int main()
{
    ll n;
    memset(dp,-1,sizeof(dp));
    while(cin>>n){
        ll temp = getans(n);
        cout<<temp<<endl;
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

BNU 26351 Space Elevator 数位dp

标签:

原文地址:http://blog.csdn.net/mengzhengnan/article/details/47664855

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!