1. 程式人生 > >【PAT甲級】1085 Perfect Sequence(二分法)

【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 (≤10​5​​) is the number of integers in the sequence, and p (≤10​9​​) is the parameter. In the second line there are N positive integers, each is no greater than 10​9​​.

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;
}

總結

學習不息,繼續加油