PAT (Basic Level) Practice 1030 完美数列 (25分) (使用upper_bound进行二分查找!)

1.题目

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤10​5​​)是输入的正整数的个数,p(≤10​9​​)是给定的参数。第二行给出 N 个正整数,每个数不超过 10​9​​。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9

输出样例:

8

2.题目分析

 使用uppper_bound函数进行二分查找

知识补充(https://blog.csdn.net/qq_40160605/article/details/80150252

从小到大的排序数组中

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

从大到小的排序数组中,重载lower_bound()和upper_bound()

lower_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
 

 3.代码


#include<iostream>
#include<algorithm>
using namespace std;
long long list[100001];
int main()
{
	long long n, p;
	cin >> n >> p;
	for (int i = 0; i < n; i++)
		cin >> list[i];
	sort(list, list + n);
	long long maxa = 0;
	for (int i = 0; i < n; i++)
	{
		int index = upper_bound(list+i, list+n, list[i] * p)-list;
		if (index == n)index--;
        while(list[index]>list[i]*p)index--;//可能所有的数字都不满足,但是upper_bound返回的是n-1
		maxa =(maxa> index - i+1)?maxa:(index-i+1);
	}
	cout << maxa;
}

 

posted @ 2020-02-22 12:18  Jason66661010  阅读(92)  评论(0编辑  收藏  举报