著名的快速排序演算法裡有乙個經典的劃分過程:我們通常採用某種方法取乙個元素作為主元,通過交換,把比主元小的元素放到它的左邊,比主元大的元素放到它的右邊。 給定劃分後的 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 個不同的正整數,每個數不超過 109。
輸出格式:
在第 1 行中輸出有可能是主元的元素個數;在第 2 行中按遞增順序輸出這些元素,其間以 1 個空格分隔,行首尾不得有多餘空格。
輸入樣例:
51 3 2 4 5
輸出樣例:
31 4 5
#include
#include
int a[
100000
], b[
100000
], v[
100000];
using
namespace std;
intmain()
sort
(a, a + n)
;for
(int i =
0; i < n; i++
) cout << cnt << endl;
for(
int i =
0; i < cnt; i++
)printf
("\n");
//l看別人的,這麼要加換行,這裡怪怪的
return0;
}
思路:快速排序的特點是主元的位置不變,即主元的位置就在排序的最終位置上。對原序列sort排序,逐個比較,當當前元素沒有變化並且它左邊的所有值的最大值都比它小的時候就是主元。用max來儲存a[i]左邊的最大值。
方法2:設定陣列leftmax存這個數左邊的最大值,leftmax[0]=0;設定rightmin存這個數右邊的最小值,rightmin[n]存乙個較大的數1000000000.
只要這個數比左邊最大的值還要大,比右邊最小的值還要小,那麼這個數就是主元。
#include
#include
#include
using namespace std;
int a[
100010];
int letfmax[
100010];
//左邊最小
int rightmin[
100010];
//右邊最大
intmain()
rightmin[n -1]
=1000000000
;for
(int i = n-
2; i>=
0; i--
)int count =0;
vector<
int>ans;
for(
int i =
0; i < n; i++)}
sort
(ans.
begin()
, ans.
end())
; cout << count << endl;
for(
int i =
0; i < ans.
size()
; i++
) cout
}
適合初步練習PAT乙級 (1019) 數字黑洞
給定任乙個各位數字不完全相同的 4 位正整數,如果我們先把 4 個數字按非遞增排序,再按非遞減排序,然後用第 1 個數字減第 2 個數字,將得到乙個新的數字。一直重複這樣做,我們很快會停在有 數字黑洞 之稱的 6174,這個神奇的數字也叫 kaprekar 常數。例如,我們從6767開始,將得到 7...
適合初步練習PAT乙級 (1064) 朋友數
如果兩個整數各位數字的和是一樣的,則被稱為是 朋友數 而那個公共的和就是它們的 朋友證號 例如 123 和 51 就是朋友數,因為 1 2 3 5 1 6,而 6 就是它們的朋友證號。給定一些整數,要求你統計一下它們中有多少個不同的朋友證號。輸入格式 輸入第一行給出正整數 n。隨後一行給出 n 個正...
適合初步練習PAT乙級 (1067) 試密碼
當你試圖登入某個系統卻忘了密碼時,系統一般只會允許你嘗試有限多次,當超出允許次數時,賬號就會被鎖死。本題就請你實現這個小功能。輸入格式 輸入在第一行給出乙個密碼 長度不超過 20 的 不包含空格 tab 回車的非空字串 和乙個正整數 n 10 分別是正確的密碼和系統允許嘗試的次數。隨後每行給出乙個以...