PAT A1085 Perfect Sequence (25分)甲级题解

Given a sequence of positive integers and another positive integer p. The sequence is said to be a perfect sequence if M≤m×p where M and m are the maximum and minimum numbers in the sequence, respectively.

Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive integers N and p, where N (≤10​5​​) is the number of integers in the sequence, and p (≤10​9​​) is the parameter. In the second line there are N positive integers, each is no greater than 10​9​​.

Output Specification:

For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.

Sample Input:

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

Sample Output:

8

解题思路:
本题将采用两种方式去完成解答
第一种:
采用局部数组平移的方式去做,将数组排序成有序数组,然后从起始点开始,设置len=0,len就是符合M<=m*p的线段长度,第一次遍历获得数组下标0开始找到的符合要求的数组段长度,这里sq[i]就是m即数组段中最小值,然后去找M的数组下标位置,数组段长度即为j-i+1,这里的技巧是从下一段,即从数组下标1开始不需要每次重新寻找符合要求数组段长,而直接选择之前选择出最大长度+1的位置开始寻找即可这里给图,因为之前找出最大长度maxLen是8所以下一次直接从1下标开始找长度为8的下一个位置,所以直接就找到20这个数字进行比较了。

第二种方法:
因为数组是有序数组,那么一定要想到二分的思路,采用upper_bound()函数,这个函数返回的是找到数组中第一个大于X的数字,例如要在1 2 3 4 4 7 7 8 中找5则会返回第一个7位置的下标,如果在vector数组中找9则会返回sq.end().

代码实现:

方法一:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
	long long p;
	int n,val;
	cin>>n>>p;
	vector<int> sq;
	while(n--) {
		scanf("%d",&val);
		sq.push_back(val);
	}
	sort(sq.begin(),sq.end());
	int len=0;
	for(int i=0; i<sq.size(); i++) {
		for(int j=i+len; j<sq.size(); j++) {
			if(sq[j]<=sq[i]*p) {
				if(j-i+1>len) len=j-i+1;
			} else break;
		}
	}
	cout<<len;
	return 0;
}

方法二:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
	long long p;
	int n,val,temp;
	cin>>n>>p;
	temp=n;
	vector<int> sq;
	while(temp--) {
		scanf("%d",&val);
		sq.push_back(val);
	}
	sort(sq.begin(),sq.end());
	int maxLen=-1,len;
	for(int i=0; i<sq.size(); i++) {
		long long ans=sq[i]*p;
//注意若找不到大于m*p的数的位置 则会返回sq.end()所以在找M值的时候说明sq.size()-1位置的值符合要求
		vector<int>::iterator it=upper_bound(sq.begin()+i,sq.end(),ans);//找到第一个大于m*p的位置   这里it是vector的迭代器
		len=it-sq.begin()-i;//计算长度
		if(len>maxLen) maxLen=len;
	}
	cout<<maxLen;
	return 0;
}

小结:很多准备PAT小伙伴应该都是考浙大的居多,希望你们在做PAT的时候多多自己思考,看完网上代码后尝试自己去修改并且多采用几种方式去实现,并达到最后觉得自己的代码比别人更加优质才好。

posted @ 2021-01-23 15:38  coderJ_ONE  阅读(135)  评论(0编辑  收藏  举报