Online JudgeLuogu-P4222

Label:逆向思维,暴力枚举

题目描述

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

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

输入

第一行为整数k。

输出

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

样例

Input

20

Output

0001321

Hint

对于30%的数据,\(k \leq 200\);

对于70%的数据,\(k \leq 10000\);

对于100%的数据,\(k \leq 200000\)。

题解

第一眼以为二分答案,但是发现每个值都依赖于前面的数字。需要依次求解。

30pts:

直接暴力枚举16进制数,检验时,暴力与前面的数比较。

时间复杂度为\(O(Ans+K^2*7)\)。其中从小到大枚举数字共\(Ans\)次,每次检验时与前面的数字一位一位比较。

70pts:

尝试打表找规律,然后你会发现,除了最后两个16进制位规律比较迷之外,剩下的前面5位规律都是显而易见的。所以直接打表后面两个位(如果代码长度限制允许的情况下),可以在O(1)时间内求解。

100pts:

这个数据范围显然如果按刚才的方案去打表不太可行(但这题也有很多其他能够AC的神奇打表+哈希做法)。下面是一种比较简洁的做法:

回到30分做法,显然还是需要依次求解,那就尝试优化后面的比较部分。采用逆向思维,当前数字与前面的数字比较,就算枚举都要O(N),不可做;那就尝试用当前的数,对后面合法/不合法的数字打上标记

原题面:至少要有3个对应位不同,才合法

其实就是:只要存在至少5个对应位相同,就不合法

比较相同显然比比较不同可做很多。对于当前弄到的一个合法数字,我们利用组合,按顺序挑出7个中的5个,将这个 组合\(mark\)了,注意,由于要控制对应位,还得记录下这是\(C_7^5=21\)中的第几个组合。

对应的,当判断当前这个数字合不合法时,也是按顺序挑出7个中的5个,如果被\(mark\)了则表示这个数字不合法;反之如果所有组合都没被\(mark\)过,表示这个数字合法。

综上,每次枚举时都可以在\(C_7^5\)的时间内判断是否合法。

代码如下:

#include<bits/stdc++.h>
#define For(a,b,c) for(a=b;a<=c;a++)
using namespace std;
int n,x[10],a,b,c,d,e,f;
bool mark[22][16][16][16][16][16];
inline void out(int c){putchar(c<=9?c+'0':c-10+'a');}
inline bool insert(){
register int id=0;
For(a,0,6)For(b,a+1,6)For(c,b+1,6)For(d,c+1,6)For(e,d+1,6){
if(mark[++id][x[a]][x[b]][x[c]][x[d]][x[e]])return 0;
}
id=0;
For(a,0,6)For(b,a+1,6)For(c,b+1,6)For(d,c+1,6)For(e,d+1,6){
mark[++id][x[a]][x[b]][x[c]][x[d]][x[e]]=1;
}
}
int main(){
scanf("%d",&n);
For(x[0],0,15)For(x[1],0,15)For(x[2],0,15)For(x[3],0,15)
For(x[4],0,15)For(x[5],0,15)For(x[6],0,15)if(insert()){
if(!--n){
int i;For(i,0,6)out(x[i]);
return 0;
}
}
}

最新文章

  1. 【JavaWeb学习】文件的上传和下载
  2. 【2016-10-17】【坚持学习】【Day8】【工厂方法模式】
  3. java基础 作业(一)
  4. Codeforces Round #381 (Div. 1) B. Alyona and a tree dfs序 二分 前缀和
  5. JAVA基础学习day13--String、StringBuilder与StringBuffer与包装类
  6. runcluvfy.sh运行结果
  7. 黄聪:wordpress如何扩展TinyMCE编辑器,添加自定义按钮及功能
  8. Android 通过广播启动另一个应用的Activity
  9. Redmine email配置
  10. [Usaco2008 Nov]Buying Hay 购买干草[背包]
  11. Apache日志分割
  12. javascript的词法作用域
  13. layer 弹出层
  14. @JsonIgnore注解可以实现不返回前端字段
  15. 细说ORM之Entity FrameWork系列(被替换)
  16. thinkphp安装不成功可能跟数据库名有关
  17. 两眼论&amp;矩阵变现理论结合打造赚钱大模式
  18. unity shader base pass and additional pass
  19. Echarts柱状图百分比显示
  20. python 之 决策树分类算法

热门文章

  1. linux上给其他在线用户发送信息(wall, write, talk, mesg)
  2. 校园商铺-2Logback配置与使用-1Logback介绍
  3. LUOGU P3048 [USACO12FEB]牛的IDCow IDs(组合数)
  4. js 自适应容器宽高
  5. MindManager全部快捷键(官方英文文档+中文翻译)
  6. Berlekamp Massey算法求线性递推式
  7. 面试系列20 生产环境中的redis是怎么部署的
  8. PropertyPlaceholderConfigurer的注意事项
  9. iOS开发系列-NSURLConnection
  10. Python全栈开发:运算符