題目
給定乙個正整數數列,和正整數 p
pp,設這個數列中的最大值是 m
mm,最小值是 m
mm,如果 m≤m
pm\le mp
m≤mp
,則稱這個數列是完美數列。
現在給定引數 p
pp 和一些正整數,請你從中選擇盡可能多的數構成乙個完美數列。
輸入格式
輸入第一行給出兩個正整數 n 和 p,其中 n(≤
105)
n(\le10^5)
n(≤105
)是輸入的正整數的個數,p(≤
109)
p(\le10^9)
p(≤109
)是給定的引數。第二行給出 n
nn 個正整數,每個數不超過 109
10^9
109。
輸出格式
在一行中輸出最多可以選擇多少個數可以用它們組成乙個完美數列。
輸入樣例
10 8輸出樣例分析2 3 20 4 5 1 6 7 8 9
首先應該想到的是給個數列排序,從到到小排序,可以用sort()
函式實現,但我為了加深對快排的理解,手寫的快排。
一開始的思路,最大值arr[n-1]
固定,然後用arr[min]*p
依次與arr[n-1]
比較,直到滿足條件,這個邏輯是不嚴謹的,因為這樣得到的個數不一定是最大的,例如序列1,2
,3,4
,5,6
,7,8
,8,20
1, 2, 3, 4, 5, 6, 7, 8, 8, 20
1,2,3,
4,5,
6,7,
8,8,
20,p = 8
,按此方法得到ans=8
,而實際最大值為9。
盡然最大值也不固定,那麼可以採用兩個left,right
,分別表示最小值下標和最大值下標,然後依次向中間靠攏,此時的策略是當arr[right] > arr[left]
時,可以compare(arr[left+1],arr[right])
或者compare(arr[left],arr[right-1])
,由此想到用遞迴,提交發現有乙個測試點超時。
於是繼續改進,放棄遞迴,定義兩層for()
迴圈,外層(i=0; i
**
#include
#include
using
namespace std;
const
int maxsize =
100000
;void
quick_sort
(int arr,
int left,
int right)
} arr[left]
= arr[i]
; arr[i]
= tmp;
quick_sort
(arr, left, j-1)
;quick_sort
(arr, i+
1, right);}
intmain()
}printf
("%d\n"
, ans)
;return0;
}
提交結果
1030 完美數列(25 分)
給定乙個正整數數列,和正整數 p,設這個數列中的最大值是 m,最小值是 m,如果 m mp,則稱這個數列是完美數列。現在給定引數 p 和一些正整數,請你從中選擇盡可能多的數構成乙個完美數列。輸入第一行給出兩個正整數 n 和 p,其中 n 10 5 是輸入的正整數的個數,p 10 9 是給定的引數。第...
1030 完美數列(25 分)
1030 完美數列 25 分 給定乙個正整數數列,和正整數 p,設這個數列中的最大值是 m,最小值是 m,如果 m mp,則稱這個數列是完美數列。現在給定引數 p 和一些正整數,請你從中選擇盡可能多的數構成乙個完美數列。輸入第一行給出兩個正整數 n 和 p,其中 n 10 5 是輸入的正整數的個數,...
1030 完美數列 (25 分)
給定乙個正整數數列,和正整數 p,設這個數列中的最大值是 m,最小值是 m,如果 m mp,則稱這個數列是完美數列。現在給定引數 p 和一些正整數,請你從中選擇盡可能多的數構成乙個完美數列。輸入第一行給出兩個正整數 n 和 p,其中 n 10 5 是輸入的正整數的個數,p 10 9 是給定的引數。第...