演算法 全排裡問題 鄰位互換法

2022-08-19 00:30:18 字數 1782 閱讀 9415

鄰位互換法,只要你在學全排列就不可不學的乙個及其有趣的演算法。

洛谷1706 全排列問題

題目描述

按照鄰位互換法的順序輸出自然數1到n所有不重複的排列,即n的全排列,要求所產生的任一數字序列中不允許出現重複的數字。

輸入格式

乙個整數n。

輸出格式

由1~n組成的所有不重複的數字序列,每行乙個序列。

每個數字保留 5個場寬。

輸入樣例

3
輸出樣例

1    2    3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

鄰位互換法其實是乙個比較容易理解的演算法,這裡我們需要定義乙個概念:如果說乙個數比它指標所指向的數小,它就處於活動狀態,當然所指向的數不能越界。此時,你可能會問這個指標是啥,其實這個指標只能指向他的下乙個數或者上乙個數,比如a[i]的指標只能指向a[i - 1]或者a[i + 1]。這個指標我們就用face[i]來記錄:當face[i] = 1時,表示a[i]指向a[i + 1];當face[i] = -1時,表示a[i]指向a[i - 1]。這樣使用起來也很方便,比如我要去找a[i]的指向位置,直接就是a[i + face[i]],不用再去if判斷了。

引入這個概念之後,我們就具體來說步驟了:

初始化全排列1, 2, 3,…… ,n。

將指標都指向左側,即face[i] = -1。

從a[1] ~ a[n]中找出處於活動狀態的最大值的位置pos。

如果沒有乙個處於活動狀態的數,代表所有的全排列已經生成完畢。

交換a[pos]和其指向的數a[pos_to]。pos_to就是a[pos]指向的位置,即pos + face[pos]。

交換face[pos]和face[pos_to]。這步千萬不要忘!

在排列中將所有的大於a[pos_to]的數的face都取反。這裡一定時a[pos_to]因為我們已經交換了a[pos]和a[pos_to]。

不停地迴圈重複步驟3、4、5、6、7,每次執行完一次就進行輸出,直到4步驟返回false,結束。

# include # include # include # include using namespace std;

const int n_max = 10;

int n;

int a[n_max + 10];

int face[n_max + 10];

bool canmove(int x)

bool permutation()

if (pos == -1) return false;

int pos_to = pos + face[pos];

swap(a[pos], a[pos_to]);

swap(face[pos], face[pos_to]);

for (int i = 1; i <= n; i++)

if (a[i] > a_max) face[i] = -face[i];

return true;

}int main()

while (permutation());

return 0;

}

全排演算法 JAVA

花了一中午終於理解了!第一種情況 1 2 3 4 無重複字元 每次固定第乙個 然後剩餘的在進行全排 1 234 2 134 3 214 4 231 接下來 234重排 2 34 3 24 4 32 其他都一樣了 直接上 public class main else private static ch...

演算法 錯排問題

錯排問題 就是一種遞推式,不過它比較著名且常用,所以要熟記!方法一 n各有序的元素應有n!種不同的排列。如若乙個排列式的所有的元素都不在原來的位置上,則稱這個排列為錯排。任給乙個n,求出1,2,n的錯排個數dn共有多少個。遞迴關係式為 d n n 1 d n 1 d n 2 d 1 0,d 2 1 ...

演算法 錯排問題

今天我們再來學習乙個比較簡單的演算法,今天我們學習的是錯排問題,什麼是錯排問題呢?這樣說吧,假如現在書架上放有10本書,每本書都有固定的位置,現在讓你重新排列這些書,讓新排好的每一本書都不在原來的位置問你有多少種排列的情況。假如我們用num陣列來代表可能的情況,那麼我們容易知道num 1 0,num...