1030 完美數列 25 分

2021-09-24 21:57:56 字數 1857 閱讀 1615

題目

給定乙個正整數數列,和正整數 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 是給定的引數。第...