hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力
题意:
定义一个排列的差分为后一项减前一项之差构成的数列,求对于n个数的排列,差分的字典序第k小的那个,n<=20,k<=1e4。
题解:
暴力打表找一遍规律,会发现,对于n个数的排列,如果想找到差分的字典序第k小的,如果k<=(n-1)!,那么对应的那个排列就是把第一位赋值为n,后面的是1~n-1的元素本身排列字典序第k小的。
比如,4个元素的排列的差分字典序最小的前6个分别是
4,1,2,3
4,1,3,2
4,2,1,3
4,2,3,1
4,3,1,2
4,3,2,1
当n为10或更多的时候,(n-1)!>1e4,便可用康托逆展开直接计算。
当n为9以下时,原先的想法是在本地暴力排序,对于每个n都取前1e4个元素交表。后来发现hdu限制提交代码大小,分析了一下,9!约等于3e5,暴力打表,过了。
#include<iostream>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
int MAXN;
LL fact[];
int tmp[];
struct Node{
int px[];//排列
int cha[];//排列的差分
int indexpx;
int indexcha;
friend bool operator > (const Node &a,const Node &b){
for(int i=;i<MAXN;i++){
if(a.cha[i]!=b.cha[i])return a.cha[i]>b.cha[i];
}
}
friend bool operator < (const Node &a,const Node &b){
for(int i=;i<MAXN;i++){
if(a.cha[i]!=b.cha[i])return a.cha[i]<b.cha[i];
}
}
//比较差分的字典序
}node[];
int ans[][];
void make_ans(){
for(int i=;i<=MAXN;i++){
node[].px[i]=i;
node[].cha[i-]=;
}
node[].indexpx=;
int i,n;
for(i=;;i++){
for(int j=;j<=MAXN;j++){
node[i].px[j]=node[i-].px[j];
}
if(!next_permutation(&node[i].px[],&node[i].px[MAXN+])){
n=i-;
break;
} for(int j=;j<MAXN;j++){
node[i].cha[j]=node[i].px[j+]-node[i].px[j];
} node[i].indexpx=i;
}
sort(node+,node++n);
for(int i=;i<=min(n,);i++){
ans[MAXN][i]=node[i].indexpx;
}
//暴力打表预处理
}
void make_fact(){
fact[]=;
for(int i=;i<=;i++){
fact[i]=fact[i-]*i;
}
}
void Cantor_invexp(int *p,int len,LL rank){
//康托逆展开
int temp[len];
for(int i=;i<len;i++){
temp[i]=i+;
}
for(int i=;i<=len;i++){
int a=rank/fact[len-i];
rank%=fact[len-i];
for(int j=;j<len;j++){
if(a== && temp[j]>){
p[i]=temp[j];
temp[j]=;
break;
}else if(temp[j]>){
a--;
}
}
}
return ;
} int main(){
make_fact();
for(int i=;i<=;i++){
MAXN=i;
make_ans();
} // return 0;
int t;
scanf("%d",&t);
while(t--){
int n,k;
scanf("%d %d",&n,&k);
if(n>=){
printf("%d",n);
Cantor_invexp(tmp,n-,1LL*k-);
for(int i=;i<=n-;i++){
printf(" %d",tmp[i]);
}
printf("\n");
}else{
Cantor_invexp(tmp,n,1LL*ans[n][k]-);
for(int i=;i<=n;i++){
printf("%d",tmp[i]);
if(i<n)printf(" ");
else printf("\n");
}
}
}
return ;
}
hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力的更多相关文章
- 2014 HDU多校弟五场J题 【矩阵乘积】
题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...
- 2014 HDU多校弟五场A题 【归并排序求逆序对】
这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...
- hdu多校第六场1005 (hdu6638) Snowy Smilel 线段树/区间最大和
题意: 给定一个矩阵,矩阵上有若干点,每个点有正或负的权值,找一个方框框住一些点使得方框中点权值最大. 题解: 离散化横纵坐标,容易将这个问题转化为在矩阵上求最大和子矩阵的问题. 普通的n*n的矩阵的 ...
- hdu多校第五场1002 (hdu6625) three arrays 字典树/dfs
题意: 给你两个序列a,b,序列c的某位是由序列a,b的此位异或得来,让你重排序列ab,找出字典序最小的序列c. 题解: 如果能找到a,b序列中完全一样的值当然最好,要是找不到,那也尽量让低位不一样. ...
- hdu多校第五场1004 (hdu6627) equation 1 计算几何
题意: 给你一个C,再给你n组a,b,让你求x取什么值的时候,$ \sum_{i=1}^n |a_i*x+b_i| =C $,要求求出解的个数,并用最简分数从小到大表示,如果有无穷多解,输出-1. 题 ...
- hdu多校第五场1006 (hdu6629) string matching Ex-KMP
题意: 给你一个暴力匹配字符串公共前缀后缀的程序,为你对于某个字符串,暴力匹配的次数是多少. 题解: 使用扩展kmp构造extend数组,在扩展kmp中,设原串S和模式串T. extend[i]表示T ...
- hdu多校第五场1007 (hdu6630) permutation 2 dp
题意: 给你n个数,求如下限制条件下的排列数:1,第一位必须是x,2,最后一位必须是y,3,相邻两位之差小于等于2 题解: 如果x<y,那么考虑把整个数列翻转过来,减少讨论分支. 设dp[n]为 ...
- 2018 HDU多校第四场赛后补题
2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...
- 2018 HDU多校第三场赛后补题
2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...
随机推荐
- 【leetcode】970. Powerful Integers
题目如下: Given two non-negative integers x and y, an integer is powerful if it is equal to x^i + y^j fo ...
- 批量新增数据(BuckCopy)
批量新增数据(BuckCopy) 使用webService传输数据时要注意,Datatable中的数据类型,以及科学计数 /// <summary> /// 批量新增数据 /// < ...
- J2EE学习篇之--Struts2技术详解
前面说到了Struts1的相关知识,下面来说一下Struts2的相关知识,我们知道现在Struts2使用的比Struts1多,Struts2已经替代Struts1成为主流的框架了... 摘要 Stru ...
- NX二次开发-Block UI C++界面Object Color Picker(对象颜色拾取器)控件的获取(持续补充)
Object Color Picker(对象颜色拾取器)控件的获取 NX9+VS2012 #include <uf.h> #include <uf_obj.h> UF_init ...
- Tomcat服务器配置参考
Coyote HTTP/1.1 Connector 概述 Coyote HTTP/1.1 Connector元素是一个支持HTTP/1.1协议的Connector组件.它使Catalina除了能够执行 ...
- ubuntu终端仿真程序和文件管理程序
1.SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单的说是Windows下登录UNIX或Linux服务器主机的软件.可以理解为ubuntu下的Terminal. 如果Sec ...
- PAT_A1130#Infix Expression
Source: PAT A1130 Infix Expression (25 分) Description: Given a syntax tree (binary), you are suppose ...
- Java反射机制调用私有方法
1.获取目标类: 每个类都有一个class属性,通过实体类的class属性获取: Class clazz = Person.class 通过对象获取. Person p1 = new Person( ...
- Codeforces 1173B Nauuo and Chess
题目链接:http://codeforces.com/problemset/problem/1173/B 思路参考:https://www.cnblogs.com/blowhail/p/1099123 ...
- vue组件通信之非父子组件通信
什么顺序不顺序的.. 先来说说非父子组件通信. 首先,我们先来了解下vue中的 1.$emit 触发当前实例上的事件,附加参数都会传给监听器回调. 2.$on 监听当前实例上的自定义事件.事件可以 ...