著名的快速排序演算法裡有乙個經典的劃分過程:我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。 給定劃分後的 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
最開始的思路是遍歷i,每次都將陣列複製到另乙個陣列中,然後sort()對i前和i後部分排序,分別取出最大值和最小值與i比較,但是這樣寫出來的**會超時。而且剛開始提交一直遇到段錯誤,找了半天發現是把10的5次方當成了10000,陣列開小了,訪問了非法記憶體。
以下是錯誤示範:
#include#includeusing namespace std;
#define maxn 10009 //開小了
int arr[maxn], ans[maxn], tmp[maxn];
int main() }
memcpy(tmp, arr, n * sizeof(int));
sort(tmp, tmp + n - 1);
if (arr[n-1] > tmp[n-2])
printf("%d\n", tot);
for (int i = 0; i < tot; i++)
return 0;
}
然後看了柳神的**,發現只需複製下來然後一次排序就可解決問題,再額外用max記錄i前的最大值即可。
ac**:
#include#includeusing namespace std;
#define maxn 100009
int arr[maxn], tmp[maxn], ans[maxn];
int main()
sort(tmp, tmp + n);
for (int i = 0; i < n; i++)
printf("%d\n", tot);
for (int i = 0; i < tot; i++)
printf("\n");
return 0;
}
關於最後的方法我也似懂非懂,睡前在琢磨一下才行。 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。則 ...