ZOJ 3505 Yet Another Set of Numbers

来源:互联网 发布:淘宝雪纺短袖衫 编辑:程序博客网 时间:2024/05/17 06:58

You are given yet another set of numbers. The numbers in this set obey these rules:

Each number will start with a non-zero digit.Each number contains at most N digits and only 0, 1, 2 and 3 are available.All the adjacent digits won't be the same (e.g. 301 is legal while 300 is illegal).The comparison is the same as strings (e.g. 1 < 123 < 20 < 21 < 3).

Given a number B belonging to this set, you have to find out the number A such that there are exactly K-1 numbers larger than A and smaller than B in this set.

Input

Input contains multiple test cases.

The first line of each test case contains two integers 0 < N < 20 and K > 0. The second line contains only a number B. It’s guaranteed that the solution exists

Output

For each case, output the number A in a single line.

Sample Input

2 5
3
5 50
12301

Sample Output

13
1021

Hint
In the first case, there are 12 numbers in the set. And they are sorted in following order:
1 < 10 < 12 < 13 < 2 < 20 < 21 < 23 < 3 < 30 < 31 < 32

解题思路:数位DP。

#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 30;ll dp[maxn];ll N, K, B;void init() {    dp[0] = 1;    for(int i = 1; i <= 20; ++i) {        dp[i] = dp[i-1] * 3;    }    for(int i = 1; i <= 20; ++i) {        dp[i] += dp[i-1];    }}int bit[maxn], blen;ll dfs1(int pos) {    if(pos < 0) {        return 0;    }    ll ret = 0;    for(int i = (pos==(blen-1)?1:0); i < bit[pos]; ++i) {        if(pos + 1 < blen) {            if(bit[pos+1] != i) {                ret += dp[N-(blen-pos)];            }        } else {            ret += dp[N-(blen-pos)];        }    }    if(pos > 0) ret++;  // 1021 10210    ret += dfs1(pos-1);    return ret;}ll solve(ll x) {    blen = 0;    while(x) {        bit[blen++] = x % 10;        x /= 10;    }    return dfs1(blen-1);}int main() {    init();    while(cin >> N >> K >> B) {        ll n1 = solve(B);        ll n2 = n1 - K;        blen = 0;        while(true) {            int id = ((blen == 0) ? 1 : 0);            while(n2 >= dp[N-blen-1]) {                if(blen > 0 && id == bit[blen-1]) {                    id++;                    continue;                } else {                    n2 -= dp[N-blen-1];                    id++;                }            }            if(id == bit[blen-1]) id++;   //////////////////////////////////////////            bit[blen++] = id;            if(n2 <= 0) break;            n2--;        }        ll tmp = 0;        for(int i = 0; i < blen; ++i) {            tmp = tmp * 10 + bit[i];        }        cout << tmp << endl;    }    return 0;}
0 0
原创粉丝点击