1045 快速排序 (25 分)
著名的快速排序演算法裡有乙個經典的劃分過程:我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。 給定劃分後的 n 個互不相同的正整數的排列,請問有多少個元素可能是劃分前選取的主元?
例如給定 n=5
n = 5
n=5, 排列是1、3、2、4、5。則:
1 的左邊沒有元素,右邊的元素都比它大,所以它可能是主元;
儘管 3 的左邊元素都比它小,但其右邊的 2 比它小,所以它不能是主元;
儘管 2 的右邊元素都比它大,但其左邊的 3 比它大,所以它不能是主元;
類似原因,4 和 5 都可能是主元。
因此,有 3 個元素可能是主元。
輸入格式:
輸入在第 1 行中給出乙個正整數 n(≤10的5次方);第 2 行是空格分隔的 n 個不同的正整數,每個數不超過 10的9次方。
輸出格式:
在第 1 行中輸出有可能是主元的元素個數;在第 2 行中按遞增順序輸出這些元素,其間以 1 個空格分隔,行首尾不得有多餘空格。
輸入樣例:
51 3 2 4 5
輸出樣例:
31 4 5
本題是一道25分的字串壓軸題,是有一定難度的,一如pat壓軸題的風格,難度主要超時上,用一般的思路只能得到一部分分。
就正常思路而言,我們只要用乙個迴圈遍歷字串中的每乙個數,再每次迴圈中再分別遍歷這個數的前一部分和後一部分,判斷是不是比這部分數都大或都小,進而判斷該數是不是主元。顯然這種解法時間複雜度達到了n的平方,最終只能過第乙個點,其餘全部超時。
再說正確的思路,我們要保證時間複雜度盡可能小(至少要小於n的平方)就要盡量避免使用巢狀迴圈。
就本題而言我們可以很明顯的發現,若乙個數為主元,那麼主元一定是它前一部分數中的最大值,它後一部分數中的最小值,總結一下就是若字串中的乙個數,包括它在內的前一部分數的最大值與後一部分數的最小值相等,那這個數就是主元,若不相等則不是。那我們不妨定義兩個陣列max和min,分別記錄前一部分數的最大值與後一部分數的最小值,最後再判斷兩者的值是否相等即可。
#include
#include
using
namespace std;
intmain()
, min[n]=;
vector<
int> v;
for(
int i =
0; i < n; i++
) cin >> a[i]
; max[0]
= a[0]
; min[n -1]
= a[n -1]
;for
(int i =
1; i < n; i++
)for
(int i = n -
2; i >=
0; i--
)for
(int i =
0; i < n; i++
) cout << v.
size()
<< endl;
if(v.
size()
==0) cout << endl;
for(
int i =
0; i < v.
size()
; i++
)return0;
}
PAT 乙級 1045 快速排序
時間限制 200 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 cao,peng 著名的快速排序演算法裡有乙個經典的劃分過程 我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。給定劃分後的n個互...
PAT 乙級 1045 快速排序
1045 快速排序 25 分 著名的快速排序演算法裡有乙個經典的劃分過程 我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。給定劃分後的 n 個互不相同的正整數的排列,請問有多少個元素可能是劃分前選取的主元?例如給定 n 5 排列是1 3 2...
PAT乙級 1045 快速排序
著名的快速排序演算法裡有乙個經典的劃分過程 我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。給定劃分後的 n 個互不相同的正整數的排列,請問有多少個元素可能是劃分前選取的主元?例如給定 n 5 n 5 n 5,排列是1 3 2 4 5。則 ...