NOIP2004P4 火星人 題解

2021-07-13 07:21:34 字數 1846 閱讀 8351

(題目描述略)

本題題意為求給定長度為 n 的數列的後第 m 個全排列(字典序)。

從右向左查詢最大的下標 i (0 ≤ i ≤ n-1) 使得 a[i] < a[i+1];

從左向右查詢最小的元素 a[j] (i+1 ≤ j ≤ n-1) 使得 a[i] < a[j];

交換 a[i] 和 a[j];

逆置翻轉 a[i+1 .. n-1]。

演算法分析:我們可以發現,第一步求出的 i 下標表示 a[i+1 .. n-1] 是乙個長度為 n-i-1 的最後乙個全排列,且 a[i .. n-1] 是乙個長度為 n-i 的非末全排列。這樣,我們可以不改變 a[0 .. i-1],而對 a[i .. n-1] 求其下乙個全排列。

因為以 a[i] 為起始的全排列已經完成,所以其構造方法必然是將 a[i] 換成 a[i+1 .. n-1] 中比 a[i] 大的且最小的數,即為 a[j]。下面我們來比較 a[i] 和 a[j+1] 之間的大小關係。顯然,a[i] ≠ a[j+1]。假設 a[i] < a[j+1],我們有 a[i] < a[j+1] < a[j],與條件 a[j] 為所有大於 a[i] 的數中最小的數矛盾。故 a[i] > a[j+1]。

由於 a[i+1] > a[i+2] > .. > a[j] > a[j+1] > .. > a[n-1],且 a[i] < a[j],a[i] > a[j+1],故 a[i+1] > a[i+2] > .. > a[j] > a[i] > a[j+1] > .. > a[n-1]。當交換 a[i] 和 a[j] 後,a[i+1 .. n-1] 必然嚴格降序排列。顯然,交換 a[i] 和 a[j] 前 a[i .. n-1] 的下乙個排列為交換 a[i] 和 a[j] 後以 a[i] 為起始的第乙個排列。於是,將 a[i+1 .. n-1] 逆置翻轉,得到原數列的下乙個全排列。

特別的,當 i 不存在時,原數列即為以 n 為長度的全排列的末排列。當然,在本題中無此類情況。

**如下:

#include"iostream"

#include"stdio.h"

using namespace std;

int number[10005];

int main()

{ freopen("martian.in","r",stdin);

freopen("martian.out","w",stdout);

int i,j,m,n,temporary;

cin>>n>>m;

for(i=0;inumber[i+1];i--);

j=i+1;

for(int k=i+2;knumber[k]))

j=k;

temporary=number[i];

number[i]=number[j];

number[j]=temporary;

for(int left=i+1,right=n-1;left對於本題,我們還可以呼叫庫函式直接出解。next_permutation是乙個定義在 algorithm 庫里的函式,功能是求乙個一維整型陣列的下乙個全排列,原理同上,用法見下。

**如下:

#include"algorithm"

#include"iostream"

#include"stdio.h"

using namespace std;

int a[10005];

int main()

{ freopen("martian.in","r",stdin);

freopen("martian.out","w",stdout);

int m,n;

cin>>n>>m;

for(int i=0;i時間複雜度:o(nm)

P1088 NOIP2004 普及組 火星人

目錄演算法求解 參考文章 題目傳送門 題目描述 人類終於登上了火星的土地並且見到了神秘的火星人。人類和火星人都無法理解對方的語言,但是我們的科學家發明了一種用數字交流的方法。這種交流方法是這樣的,首先,火星人把乙個非常大的數字告訴人類科學家,科學家破解這個數字的含義後,再把乙個很小的數字加到這個大數...

NOIP2004 火星人(全排列)

題目描述 火星人共有n個手指,每個手指分別代表著1 n共n個數,可以通過改變這個這n個手指的順序來改變值的大小。但是人類想要和火星人交流,就必須通過科學家,科學家先將火星人講的話 手指表示的數 翻譯成我們能理解的語言 如火星人共3個手指,則123 132 213 231 312 321分別代表1 2...

落谷P1088 火星人

題目描述 人類終於登上了火星的土地並且見到了神秘的火星人。人類和火星人都無法理解對方的語言,但是我們的科學家發明了一種用數字交流的方法。這種交流方法是這樣的,首先,火星人把乙個非常大的數字告訴人類科學家,科學家破解這個數字的含義後,再把乙個很小的數字加到這個大數上面,把結果告訴火星人,作為人類的回答...