牛客PAT1059

题目链接:https://www.nowcoder.com/pat/5/problems?page=3

思路:step1:排序

   step2:对i从0-N-1逐个判断:以a[i]为最小数时,最多能选多少个数

其中,step2使用二分查找,求出结果

#include <iostream>
#include <algorithm>
#define MAXN 100003
using namespace std;
int findmax(int i);//求出以a[i]为最小数时,最长的序列
void solve();
bool Perfect(int l,int h);//判断是不是完美序列?

int p,N,ans;
int a[MAXN];
int main()
{
    cin>>N>>p;
    for( int i = 0;i<N;i++) cin>>a[i];
    sort(a,a+N);
    ans = 0;
    solve();
    cout<<ans<<endl;
    return 0;
}
void solve(){
    for(int i = 0;i<N;i++){
        if( ans > N-i) return ;//i都比N-ans大了,后面也没判断的必要了。。。
        int tmp = findmax(i);
        if( tmp > ans) ans = tmp;

    }
}
int findmax(int i){
    int l = i;
    int h = N-1;
    int mid;
    while( l<=h ){//二分查找
        mid = (l+h)/2;
        if( Perfect(i,mid)) l=mid+1;
        else h=mid-1;
    }
  //正常情况下,l和h是一个满足,另一个不满足。注意,但有时,会出现越界,导致判断错误。。。。
    if( Perfect(i,l) && l<N) return l-i+1;
    else if( Perfect(i,h) && h>=i) return h-i+1;
    else return 0;
}
bool Perfect(int l,int h){
    long long tmp = a[l]*p;
    return tmp>=a[h];
}

猜你喜欢

转载自www.cnblogs.com/ShuihanYi/p/9004604.html