B1030 完美数列 (25 分)

这是一道二分法的题目,许久不使用二分法,感觉有点生疏。

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100000+5;
vector<int> vec;
int N,p;
int binarySearch(int i,long long x){
    if(vec[N-1]<=x) return N;
    int l=i+1,r=N-1,mid;
    while(l<r){
        mid=(l+r)/2;
        if(vec[mid]<=x)l=mid+1;
        else r=mid;
    }
    return l;
}
int main(){
    scanf("%d %d",&N,&p);
    for(int i=0;i<N;i++){
        int x;
        scanf("%d",&x);
        vec.push_back(x);
    }
    //sort
    sort(vec.begin(),vec.end());
    int ans = 1;//max length=1
    for(int i=0;i<N;i++){
        //vec[i+1]~vec[n-1]
        int j=binarySearch(i,(long long)vec[i]*p);
        ans=max(ans,j-i);//update
    }
    printf("%d
",ans);
    return 0;
}

注意点:

  1. vec[i] x p,已经超出了int的范围,用long long。
  2. 二分的前提是先排序。
  3. 通过指针l与指针r不断地缩小搜索范围,指针mid当中介,当lr相等时,查询结束。

以下,用c++提供的upper_bound函数解决,内部也采用二分实现。

#include<bits/stdc++.h>
using namespace std;
vector<int> vec;
int N,p;
int main(){
    scanf("%d %d",&N,&p);
    for(int i=0;i<N;i++){
        int x;
        scanf("%d",&x);
        vec.push_back(x);
    }
    //sort
    sort(vec.begin(),vec.end());
    int ans = 1;//max length=1
    for(int i=0;i<N;i++){
        //vec[i+1]~vec[n-1]
        int j=upper_bound(&vec[i+1],&vec[N],(long long)vec[i]*p)-&vec[0];
        ans=max(ans,j-i);//update
    }
    printf("%d
",ans);
    return 0;
}
keep going
原文地址:https://www.cnblogs.com/MarkKobs-blog/p/10569444.html