[原创]HDU 1027 Ignatius and the Princess II [康托逆展开]【数学】

2016-11-04 16:16:54 Tabris_ 阅读数:240


博客爬取于2020-06-14 22:42:51
以下为正文

版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53036273


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1027

--------------------------------------------.

Ignatius and the Princess II

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7182 Accepted Submission(s): 4264

Problem Description
Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, “I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too.” Ignatius says confidently, “OK, at last, I will save the Princess.”

“Now I will show you the first problem.” feng5166 says, “Given a sequence of number 1 to N, we define that 1,2,3…N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it’s easy to see the second smallest sequence is 1,2,3…N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It’s easy, isn’t is? Hahahahaha…”
Can you help Ignatius to solve this problem?

Input
The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub’s demand. The input is terminated by the end of file.

Output
For each test case, you only have to output the sequence satisfied the BEelzebub’s demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.

Sample Input
6 4
11 8

Sample Output
1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10

Author
Ignatius.L

--------------------------------------------.

题目大意:
就是求有n个数的第m个排列

解题思路:
由于m≤1e5 但是不知道数据量到底是多大 所以不应该采取暴力的做法 正解应该是康托逆展开

但是这时候考虑n比较大 到了1000,这时候如果直接康托逆展开的话 阶乘会爆掉 所以不可取
这时候看了一下m值只有1e5 那么就能知道变化的序列里面也只有后面几位而已
这时候暴力跑一下 发现 只有后8位的顺序有变化
这时候我们只要单独把8位逆展开就可以了

注意的是n小于8的时候 不要算多就可以了

展开过程比较水 随便写写就好了 如果不是特别了解康拓展开 可以戳这里<-目录里面有

附本题AC代码
--------------------------------------------------------------------------------------.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# include <stdio.h>
# include <iostream>
# include <algorithm>
# include <string.h>
# include <cmath>
using namespace std;

# define INF 0x3f3f3f3f
# define pb push_back
# define abs(a) ((a)>0?(a):-(a))
# define min(a,b) ((a)>(b)?(a):(b))
# define lalal puts("*******")

typedef long long int LL ;
typedef unsigned long long int LLu ;
/*******************************/

const int MOD = 10086;
const int N = 1e7+5;

int prime[700000],kp;
bool Is_or[N];

char s1[30];
bool vis[30];
LL a[30];
LL jiecheng[30];

void init()
{
jiecheng[0]=1;
for(int i=1; i<=12; i++)
jiecheng[i]=jiecheng[i-1]*i;
return ;
}

LL Cantor_expansion(char s1[])
{
LL x=0;
int rk=0;
for(int i=0; i<12; i++)
{
rk=0;
for(int j=11; j>i; j--)
if(s1[i]>s1[j])rk++;
a[i]=rk;
}
for(int i=0; i<12; i++)
x+=a[i]*jiecheng[11-i];
return x+1;
}

void Cantor_inexpansion(int len,int x){

int li=(len>=8?8:len);
int ind=0,tem;
for(int i=0;i<li;i++) vis[i]=0;
for(int i=li-1;i>=0;i--){
ind=0;
tem = x/jiecheng[i];

for(int j=0;j<li;j++){
if(vis[j]) continue;
if(ind==tem) {a[i]=j;break; }
ind++;
};
vis[a[i]]=1;
x%=jiecheng[i];
}

for(int i=1;i<=len-li;i++)
if(i==1)printf("1");else printf(" %d",i);

for(int i=li-1;i>=0;i--)
if(a[i]+len-li+1==1)printf("1");
else printf(" %d",a[i]+len-li+1);
puts("");

return ;
}

int main()
{
init();
int n,m;
while(~scanf("%d%d",&n,&m)){
Cantor_inexpansion(n,m-1);
}
return 0;
}

----------------------------------------------------------------------------------------.