Perfect Sequence

1085 Perfect Sequence

原题链接

PAT 甲级 1085 Perfect Sequence

解题思路

给定一个数p,如果一个序列满足,M≤m×p,则是完美数列,m和M分别是序列中的最大值和最小值。

  1. 显然,首先对序列进行排序,完美序列一定是该序列的一个连续子序列。
  2. 排好序后,从小到大枚举每个元素(不一定从首元素开始的是最长的),假定完美序列从该元素开始,此时m、p都已知,如何确定M的位置呢,令 x = m×p,即在序列中寻找第一个大于x的元素,M即为该元素前一个元素,(因为可能有多个重复元素,所以不能找第一个大于等于x的元素)。

upperbound函数:

int upperbound(int l, int r, long long x){//在num数组 [l, r] 中寻找,返回第一个大于x的元素位置
	long long mid; 
	while(l<r){//l==r夹出了答案位置
		mid = l+(r-l)/2;
		if(num[mid] > x){
			r = mid;
		} 
		else{
			l = mid+1;
		}
	} 
	return l;
}

源代码

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100010;
long long num[maxn];
int upperbound(int l, int r, long long x){//返回第一个大于x的元素位置
	long long mid; 
	while(l<r){//l==r夹出了答案位置
		mid = l+(r-l)/2;
		if(num[mid] > x){
			r = mid;
		} 
		else{
			l = mid+1;
		}
	} 
	return l;
}
int main(){
	int n;
	long long p;
	scanf("%d%lld",&n,&p);
	for(int i=0; i<n; i++){
		scanf("%lld",&num[i]);
	}
	sort(num, num+n);
//	for(int i=0; i<n; i++){
//		printf("%lld ",num[i]);
//	}
//	printf("\n");
	int res = -1, j;
	for(int i=0; i<n; i++){
		j = upperbound(i,n,num[i]*p);
		res = max(res, j-i);//j-i为完美序列的元素个数 
	}
	printf("%d",res);
	return 0;
}
发布了110 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40486952/article/details/104212110
今日推荐