著名的快速排序演算法裡有乙個經典的劃分過程:我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。 給定劃分後的 n 個互不相同的正整數的排列,請問有多少個元素可能是劃分前選取的主元?
例如給定 $n = 5$, 排列是1、3、2、4、5。則:
因此,有 3 個元素可能是主元。
輸入在第 1 行中給出乙個正整數 n(≤105); 第 2 行是空格分隔的 n 個不同的正整數,每個數不超過 109。
在第 1 行中輸出有可能是主元的元素個數;在第 2 行中按遞增順序輸出這些元素,其間以 1 個空格分隔,行首尾不得有多餘空格。
5
1 3 2 4 5
3
1 4 5
本題考察一些資料結構跟程式設計技巧,感覺難度不是很大,但通過率比較低也是很奇怪。本題要找的數需要滿足在它之前的數都比它小,在它之後的數都比它大。也就是說對於每個數,需要找出它前面的數字序列中的最大值和它後面的數字序列中的最小值。
我的做法就是定義兩個陣列num1和num2,num1[i]儲存原始序列中第乙個數到第i個數之間的最大值,num2[i]儲存原始序列中倒數第乙個數到第i個數中的最小值(方向相反)。然後判斷原始序列中第i個數與num1[i]、num2[i]的大小關係即可。
第一遍交上去通過之後對我的程式做了一些優化。首先是找最大值的操作可以與輸入操作一起完成,因為二者都是在對陣列進行順序的遍歷,所以可以放到乙個for語句中完成。
其次是可以省去num2陣列,原本我的程式中計算num2使用了乙個單獨的for迴圈,之後又用了乙個for迴圈來判斷每個數是否符合題意。這個改動是比較大的,下面結合**來理解一下:
優化前:
for(int i=n-1;i>=0;i--)
優化後省去了num2陣列,且將兩個過程放到一起進行:
vectorres;
for(int i=n-1,min=num[n-1];i>=0;i--)
源**如下:
#includeusing namespace std;
int main()
vectorres;
for(int i=n-1,min=num[n-1];i>=0;i--)
sort(res.begin(),res.end());
cout
}
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。則 ...