PAT甲級 1085 Perfect Sequence 二分法

解題思路:

二分,O(nlogn)的複雜度纔可以跑10^5的數據。直接找到第一個不滿足條件的下標j,然後j-1即使最後一個滿足條件的下標(即所求下標)。二分函數要麼直接調用函數Upper_bound,要麼自己寫。

注意

1.數據109,由於要查找p*m,可能達到1018,故使用long long 來保存數據
2.要注意最大數據也滿足M<=mp的情況
1)upper_bound若沒找到大於所給數據的數據,則返回end
2)若自己寫函數,則應注意[left, right]要包含所有可能取值,即[0,n](最大的數據也<=m
p),而非[0,n-1]

方法1.upper_bound(精簡代碼)

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include <map>
#define LL long long
using namespace std;

const int maxn = 100000+5;
vector<long long> num;

bool cmp(long long a, long long b){
    return a < b;
}

int main(){
    int n;
    long long p;
    scanf("%d%lld", &n, &p);
    for(int i = 0; i < n; i++){
        long long x;
        scanf("%lld", &x);
        num.push_back(x);
    }
    int maxLen = 0;
    sort(num.begin(), num.end(), cmp);
    for(int i = 0; i < n; i++){
        //找到序列裏第一個>m*p的下標
        int j = upper_bound(num.begin()+i, num.end(), num[i]*p) - num.begin();
        if(j <= n) maxLen = max(maxLen, j-i+1-1);
        //可能找不到滿足條件的值。
        //注意這裏找的是第一個不滿足條件的下標,而求的應該是-1後的值
    }
    printf("%d\n", maxLen);
    return 0;
}

方法2:自己實現輸出第一個不滿足條件的數組下標

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include <map>
#define LL long long
using namespace std;

const int maxn = 100000+5;
vector<long long> num;
int n;
//數據用long long,題目m*p,而p<=10^9,用int最後一個樣例會數據溢出

bool cmp(long long a, long long b){
    return a < b;
}
//如果沒有更大的數
int binarySearch(int i, long long x){
    int l = i, r = n;//可能所有元素都比它小..
    while(l < r){
            //對[left,right]來說,Left==right意味着找到唯一位置
        int mid = (l + r)/2;
        if(num[mid] > x){
            r = mid;
        }else if(num[mid] <= x){
            l = mid+1;
        }
    }
    return l;

}

int main(){
    long long p;
    scanf("%d%lld", &n, &p);
    for(int i = 0; i < n; i++){
        long long x;
        scanf("%lld", &x);
        num.push_back(x);
    }
    int maxLen = 0;
    sort(num.begin(), num.end(), cmp);
   
    for(int i = 0; i < n; i++){
        int j = binarySearch(i, num[i]*p);
        maxLen = max(maxLen, j-i);
    }
    printf("%d\n", maxLen);
    return 0;
}

方法3:two pointer法(還沒看,之後補充)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章