题目描述
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; }