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 (≤105) is the number of integers in the sequence, and p (≤109) is the parameter. In the second line there are N positive integers, each is no greater than 109.
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的时候多多自己思考,看完网上代码后尝试自己去修改并且多采用几种方式去实现,并达到最后觉得自己的代码比别人更加优质才好。