Description

你需要给一批商品编号, 其中每个编号都是一个 7 位 16 进制数 (由 0~ 9, a-f 组成). 为了 防止在人工处理时不小心把编号弄错, 要求任意两个编号至少有三个位置对应的数字不相同. 第一个编号为 0000000, 第二个编号为不违反上述规定的前提下最小的编号,. ...... , 每次分配一个新编号时, 总是选择不和前面编号冲突的最小编号 (注意编号都是 16 进制数, 可以比较大小). 按此规律, 前面若干编号分别是:0000000, 0000111, 0000222, ..., 0000fff, 0001012, 0001103, 0001230, 0001321, 0001456, ...

输入 k, 你的任务是求出第 k 小的编号.

Input

第一行为整数 k.

Output

输出第 k 小的编号 (字母必须输出小写). 输入保证这个编号存在.

Sample Input

20

Sample Output

0001321

Data Range

编号 1-3 4-7 8-10
k \(\leq 200\) \(\leq 10000\) \(\leq 200000\)

Solution

发现又是一道恶心高维 dp...... 下方题解粘自 http://blog.csdn.net/sunshinezff/article/details/51216959

可以发现其实只需要保存 5 个位置.

因为至少有两个位置的数不同, 如果这两个位置不同, 那至少有三个位置不同.

从 7 个数中选 5 个数的方案有 21 种.

\(dp[x][a][b][c][d][e]\) 表示第 x 种排列 5 个数分别是 \(a, b, c, d, e\);

暴力枚举即可.

Source Code


#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;
typedef long long lli;
const int maxn = 16, maxm = 24;

int n, res; // That means a lot of memory...
bool dp_arr[maxm][maxn][maxn][maxn][maxn][maxn];
#define dp(_1,_2,_3,_4,_5,_6) dp_arr[_1][_2][_3][_4][_5][_6]

void print_hex(int a, int b, int c, int d, int e, int f, int g) {
    #define print_hex_s(__x) if(__x<10)printf("%d",__x);else printf("%c",__x-10+'a')
    // #define print_hex_s(__x) printf("%d ", __x);
    print_hex_s(a); print_hex_s(b); print_hex_s(c); print_hex_s(d);
    print_hex_s(e); print_hex_s(f); print_hex_s(g);
    printf("\n"); return ; }

#define forhex(__x) for(int __x=0;__x<=15;__x++)
#define breakall a=16;b=16;c=16;d=16;e=16;f=16;g=16

int main(int argc, char** argv)
{
    scanf("%d", &n);
    res = 0;
    forhex(a) forhex(b) forhex(c) forhex(d) forhex(e) forhex(f) forhex(g) {
        // print_hex(a, b, c, d, e, f, g);
        if (!dp(1, c, d, e, f, g)  && !dp(2, b, d, e, f, g)  &&
            !dp(3, b, c, e, f, g)  && !dp(4, b, c, d, f, g)  &&
            !dp(5, b, c, d, e, g)  && !dp(6, b, c, d, e, f)  &&
            !dp(7, a, d, e, f, g)  && !dp(8, a, c, e, f, g)  &&
            !dp(9, a, c, d, f, g)  && !dp(10, a, c, d, e, g) &&
            !dp(11, a, c, d, e, f) && !dp(12, a, b, e, f, g) &&
            !dp(13, a, b, d, f, g) && !dp(14, a, b, d, e, g) &&
            !dp(15, a, b, d, e, f) && !dp(16, a, b, c, f, g) &&
            !dp(17, a, b, c, e, g) && !dp(18, a, b, c, e, f) &&
            !dp(19, a, b, c, d, g) && !dp(20, a, b, c, d, f) &&
            !dp(21, a, b, c, d, e)) {
            res++;
            if (res >= n) {
                print_hex(a, b, c, d, e, f, g);
                breakall;
            }
            dp(1, c, d, e, f, g)  = true; dp(2, b, d, e, f, g)  = true;
            dp(3, b, c, e, f, g)  = true; dp(4, b, c, d, f, g)  = true;
            dp(5, b, c, d, e, g)  = true; dp(6, b, c, d, e, f)  = true;
            dp(7, a, d, e, f, g)  = true; dp(8, a, c, e, f, g)  = true;
            dp(9, a, c, d, f, g)  = true; dp(10, a, c, d, e, g) = true;
            dp(11, a, c, d, e, f) = true; dp(12, a, b, e, f, g) = true;
            dp(13, a, b, d, f, g) = true; dp(14, a, b, d, e, g) = true;
            dp(15, a, b, d, e, f) = true; dp(16, a, b, c, f, g) = true;
            dp(17, a, b, c, e, g) = true; dp(18, a, b, c, e, f) = true;
            dp(19, a, b, c, d, g) = true; dp(20, a, b, c, d, f) = true;
            dp(21, a, b, c, d, e) = true;
        }
    }
    return 0;
}