問題描述:
n 個元素有 n!個不同的排列。將這 n!個排列按字典序排列,並編號為 0,1,…,
n!-1。每個排列的編號為其字典序值。例如,當 n=3 時,6 個不同排列的字典序值如下:
字典序值 0 1 2 3 4 5
排列 123 132 213 231 312 321
´程式設計任務:
給定 n 以及 n 個元素的乙個排列,計算出這個排列的字典序值,以及按字
典序排列的下乙個排列。
´資料輸入:
由檔案 input.txt 提供輸入資料。檔案的第 1 行是元素個數 n。接下來的 1 行是 n 個元素
的乙個排列。
´結果輸出:
程式執行結束時,將計算出的排列的字典序值和按字典序排列的下乙個排列輸出到檔案
output.txt 中。檔案的第一行是字典序值,第 2 行是按字典序排列的下乙個排列。
輸入檔案示例 輸出檔案示例
input.txt output.txt
82 6 4 5 8 1 7 3
8227
2 6 4 5 8 3 1 7
【題解】
比較經典的做法是用康拓展開直接求。
這裡介紹另外一種做法。
就是對於1..n的乙個排列a[1..n]
首先它肯定大於首元素為1..a[1]-1的排列。
這樣的排列有(a[1]-1)(n-1)!個
然後我們接著考慮a[2..n]
我們可以這樣。
把a[2..n]當中比a[1]大的數字都減去1.
這樣的話。
a[2..n]就是1..n-1的乙個排列了。
我們的問題轉化成求a[2..n-1]的排名。
這樣我們就還是能用相同的方法來做這個問題了。
即累加(a[2]-1)(n-2)!
以此類推便可以解決這個問題了。
逆過來的話。
也還是很簡單。
顯然a[i]=p/(n-i)! + 1
然後for i 從n到1,對於j>i,如果a[i]<=a[j],那麼a[j]遞增
【**】
#include #define ll long long
using namespace std;
const int n = 15;
int n;
int a[n+10],b[n+10];
ll f[n+10];
int main()
printf("%i64d\n",ans1);
//ans1++讓你求出字典序為ans1的序列
ans1++;
for (int i = 1;i <= n;i++)
for (int i = n-1;i>=1;i--)
}for (int i = 1;i <= n;i++)
return 0;
}
Swust OJ 541 排列字典序問題
time limit ms 2000 memory limit kb 65535 n個元素有n 個不同的排列。將這n 個排列按字典序排列,並編號為0,1,n 1。每個排列的編號為其字典序值。例如,當n 3時,6 個不同排列的字典序值如下 0 1 2 3 4 5 123 132 213 231 312...
排列的字典序問題
問題描述 n個元素共有n 個不同的排列。將這n個元素按照字典序排列 可以從0編號,直至n 1。例如,當n 3時,6個不同排列的字典序值為 0 1 2 3 4 5 123 132 213 231 312 321 程式設計任務 給定n以及n個元素的乙個排列,計算出這個排列的字典序值 給定乙個字典序列,計...
hdu 4248排列問題
一看就可以用母函式做,不過好久沒練dp了,所以還是用dp做了。用dp i j 表示前i種石頭排出j個出來的種數,當考慮第i種石頭石,列舉其使用的個數即可。wa了好幾次,是整數相乘精度的問題,使用long long就過了。hdu1004 win.cpp created on 2012 7 24 aut...