列表

详情


NC19925. [CQOI2012]编号

描述

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

输入描述

第一行为整数k。

输出描述

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

示例1

输入:

20

输出:

0001321

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 659ms, 内存消耗: 12108K, 提交时间: 2023-01-20 21:25:10

#include <bits/stdc++.h>
using namespace std;

char s[20] = "0123456789abcdef";
int cnt, k;
bool dp[22][17][17][17][17][17];
array<int, 7> tmp, v, C[22];

void dfs1 (int t, int d) {
	if (d >= 5) { C[cnt++] = tmp; return ;}
	for (int i = t; i < 7; i++) {
		tmp[d] = i;
		dfs1 (i + 1, d + 1);
	}
}

void dfs2 (int d) {
	if (k == 0) return ;
	if (d >= 7) {
		for (int i = 0; i < cnt; i++) {
			if(dp[i][tmp[C[i][0]]][tmp[C[i][1]]][tmp[C[i][2]]][tmp[C[i][3]]][tmp[C[i][4]]]) return ;
		}
		for (int i = 0; i < cnt; i++) {
			dp[i][tmp[C[i][0]]][tmp[C[i][1]]][tmp[C[i][2]]][tmp[C[i][3]]][tmp[C[i][4]]] = 1;
		}
		if (--k == 0) {
			for (int i = 0; i < 7; i++)
				cout << s[tmp[i]];
		}
		return ;
	}
	for (int i = 0; i < 16; i++) {
		tmp[d] = i;
		dfs2 (d + 1);
	}
}

void solve() {
	cin >> k;
	dfs1 (0, 0);
	dfs2 (0);
}

signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	solve();
	return 0;
}

上一题