排列的字典序問題
阿新 • • 發佈:2019-02-01
問題描述:
n個元素{1,2,, n }有n!個不同的排列。將這n!個排列按字典序排列,並編號為0,1,…,
n!-1。每個排列的編號為其字典序值。例如,當n=3時,6 個不同排列的字典序值如下:
字典序值 0 1 2 3 4 5
排列 123 132 213 231 312 321
演算法設計:
給定n以及n個元素{1,2,, n }的一個排列,計算出這個排列的字典序值,以及按字典
序排列的下一個排列。
資料輸入:
輸出元素個數n。接下來的1 行是n個元素
{1,2,, n }的一個排列。
結果輸出:
將計算出的排列的字典序值和按字典序排列的下一個排列輸出。第一行是字典序值,第2行是按字典序排列的下一個排列。
Sample Input
8
2 6 4 5 8 1 7 3
Sample Output
8227
2 6 4 5 8 3 1 7
程式碼僅供參考,勿拷貝作為課堂派作業!!!
題意:給出一個序列,求這個序列是全排列中的第幾個,以及求出下一個排列。。。
思路:
我們可以從從開始算,因為不能有重複,以1開頭的後面有7位數有1*7!,然後以2開頭的後面有六位數,但第二位要小於6,即有1、3、4、5滿足,有4*6!,然後以26...開頭的後面有5位數,要求第三位要小於4,即有1,3滿足,有2*5!,,,依次類推。。。
找到規律為:看後面有幾個比當前數小的,,比如2後面比2小的只有1,6後面比6小的有4個,4後面比4小的有2個。。即:
然後說一下STL庫中的next_permutation和prev
程式碼:
#include<stdio.h> #include <algorithm> #define ll long long using namespace std; int f(int n) { if(n==1) return 1; return n*f(n-1); } int main() { ll n,i,j; ll a[1000]; ll sum=0; while(scanf("%I64d",&n)) { for(i=0;i<n;i++) scanf("%I64d",&a[i]); for(i=0;i<n-1;i++) { ll count=0; for(j=i+1;j<n;j++) { if(a[j]<a[i]) count++; } sum+=(count*f(n-i-1)); } printf("%I64d\n",sum); if(next_permutation(a,a+n)) { for(int i=0;i<n;i++) printf("%I64d ",a[i]); printf("\n"); } } return 0; }