【PAT甲級】1085 Perfect Sequence(二分法)
Given a sequence of positive integers and another positive integer p. The sequence is said to be a perfect sequence if M≤m×p where Mand m are the maximum and minimum numbers in the sequence, respectively.
Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.
Input Specification:
Each input file contains one test case. For each case, the first line contains two positive integers N and p, where N (≤105) is the number of integers in the sequence, and p (≤109) is the parameter. In the second line there are N positive integers, each is no greater than 109.
Output Specification:
For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.
Sample Input:
10 8
2 3 20 4 5 1 6 7 8 9
Sample Output:
8
題目大意
這題給出一個數字序列,然後要找到序列中儘量多的數字組成完美序列。完美序列的概念是給出一個數字p,然後序列中最小值為m,最大值為M,如果滿足M≤m×p則序列為完美序列。
個人思路
這題是乙級的1035,當時是直接想,這裡用了二分法。
這題先將給出的序列進行從小到大的排序,然後逐位假設這位數字為完美序列的第一個數,然後二分查詢第剩下的數字中第一個滿足num > m×p的數字,然後這個數字的前一個數字即為完美序列的最大值。然後更新最長的完美序列長度並輸出即可。
實現程式碼
#include <cstdio>
#include <algorithm>
#include <iostream>
#define ll long long
using namespace std;
const int maxn = 100005;
// 二分查詢,尋找比x大的第一個數字的下標
int binary_search(ll a[], int left, int right, ll x) {
int mid;
while (left < right) {
mid = (left+right) / 2;
if (a[mid] > x) right = mid;
else left = mid + 1;
}
return left;
}
int main() {
// 輸入
int n, ans = 0;
ll nums[maxn], p;
cin >> n >> p;
for (int i = 0; i < n; i ++) {
cin >> nums[i];
}
// 排序
sort(nums, nums+n);
// 對將每個數字都看作是序列的第一個數字,然後尋找滿足條件的最長序列
for (int i = 0; i < n; i ++) {
int pos = binary_search(nums, i, n, nums[i]*p)-1;
if (pos - i + 1 > ans) ans = pos - i + 1;
}
cout << ans;
return 0;
}
總結
學習不息,繼續加油