题目描述
Did you remember that simple problem permutation of five? Now, TY has meeted another problem about permutation. Help him.
You are given two numbers, n and m. The permutation is based on n digits.
First, you should point out the m th permutation of all permutations in an ascend order. Than reverse that permutation and print the rank of that reversed permutation of all permutations in an ascend order.
输入
Multiple cases( > 1000). Each case contains a line with two integer, n,m. (1 <= n <= 9, 1 <= m <= n!)
输出
Each case a line, the mth permutation and the rank, seperated by a space.
样例输入
5 1
5 10
样例输出
12345 120
13452 48
#include<iostream>
using namespace std;
int n, m;
bool used[10];
int a[9];
int fac[10];
void factorial(){
int i;
fac[0] = 1;
for (i = 1; i < 10; i++)
fac[i] = i*fac[i - 1];
}
int getNum(int i){
int j,k=0;
for (j = 1; k<i;j++)
if (used[j] == false)k++;
return j-1;
}
void find(){
int i;
for (i = 0; i < n; i++){
a[i]=getNum( m / fac[n - 1-i]+1);
used[a[i]] = true;
m %= fac[n-i - 1];
}
}
void turn(){
int i, j;
for (i = 0; i * 2 < n; i++){
j = a[i];
a[i] = a[n - i-1];
a[n - i-1] = j;
}
}
int which(int n){
int i, j=0;
for (i = 0; i < n; i++)
{
if (used[i] == false)j++;
}
return j;
}
int toNum(){
int i, k = 0;
for (i = 0; i < n; i++){
k += fac[n-i-1] * (which(a[i])-1);
used[a[i]] = true;
}
return k;
}
int main(){
//freopen("in.txt", "r", stdin);
factorial();
while (scanf("%d%d",&n,&m)!=-1){
memset(used, 0, sizeof(used));
m--;
find();
int i;
for (i = 0; i < n; i++)
printf("%d",a[i]);
cout << " ";
turn();
memset(used, 0, sizeof(used));
printf("%d\n", toNum() + 1);
}
return 0;
}