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;
}