题目

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

题目分析

已知正整数序列seq[N],最大值为M,最小值为m,已知另一个正整数p(<=10^9),从数列中抽出一部分数字,求可以满足M<=m*p的数字最多抽取个数

要满足M<=mp抽取的数字最多(即:M与m中间夹的数字最多),需要取所有满足M<=mp的情况中,m最小,M最大

解题思路

思路 01(最优、二分查找、查找M复杂度O(logn))

  1. 对seq[N]升序排序
  2. 依次遍历seq[i],在i+1到N之间,找到最大满足M<=mp的数字(即:第一个满足大于mp的数字下标j-1)

思路 02 (two pointer、查找M复杂度O(n))

  1. 对seq[N]升序排序
  2. 依次遍历seq[i],j初始为0,开始从上次j往后找(因为i+1后m增大,m*q>=M,所以M增大,j只能在上次j之后)

易错点

  1. p(<=10^9),所以m*p有可能超过int范围,数组元素类型需为long long,否则第5个测试点错误
  2. 取第一个大于mp的数字下标-1,而不是第一个大于等于mp的数字下标(因为大于的情况下要-1,等于的情况下不需要-1,处理麻烦)
  3. 思路02中,只能从前往后找第一个不满足条件m*q>=M的,不能从后往前找最后一个满足条件的(测试点4超时)

Code

Code 01

#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc,char * argv[]) {
int n,p;
scanf("%d %d",&n,&p);
long long seq[n]= {0}; // 若为int,第5个测试点错误
for(int i=0; i<n; i++) {
scanf("%d",&seq[i]);
}
sort(seq,seq+n);
int maxnum=0;
for(int i=0; i<n; i++) {
// 二分查找
int left=i+1,right=n;
int mid = left+((right-left)>>1);
while(left<right) {
mid = left+((right-left)>>1);
if(seq[mid]>seq[i]*p) { //若是求第一个大于等于seq[i]*p,测试点2错误
right=mid;
} else {
left=mid+1;
}
}
if(right-i>maxnum)maxnum=right-i;
}
printf("%d",maxnum);
return 0;
}

Code 01

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int main(int argc,char * argv[]) {
int n,p;
scanf("%d %d",&n,&p);
long long seq[n]= {0}; // 若为int,第5个测试点错误
for(int i=0; i<n; i++) {
scanf("%d",&seq[i]);
}
sort(seq,seq+n);
// 写法一:
int maxnum=0,j = 0;
for(int i=0; i<n; i++) {
while(j<n&&seq[i]*p>=seq[j]) j++;
maxnum=max(maxnum,j-i);
} // 写法二:
// int i=0,j=0,maxnum=1;
// while(i<n&&j<n) {
// while(j<n&&seq[j]<=(long long)seq[i]*p) {
// maxnum=max(maxnum,j-i+1);
// j++;
// }
// i++;
// } /*
使用下面代码,第四个测试点超时
j从后往前找最后一个满足条件的,测试点4超时
*/
// int maxnum=0,prej=0; //prej用于记录上次j的位置,之后的j只可能比prej大,m*p>=M;i+1因为m增大了,所以M一定增大
// for(int i=0; i<n; i++) {
// int j = n-1;
// while(prej<=j&&seq[i]*p<seq[j]) j--;
// maxnum=max(maxnum,j-i+1);
// prej=j;
// } printf("%d",maxnum);
return 0;
}

PAT Advanced 1085 Perfect Sequence (25) [⼆分,two pointers]的更多相关文章

  1. 1085 Perfect Sequence (25 分)

    Given a sequence of positive integers and another positive integer p. The sequence is said to be a p ...

  2. 【PAT甲级】1085 Perfect Sequence (25 分)

    题意: 输入两个正整数N和P(N<=1e5,P<=1e9),接着输入N个正整数.输出一组数的最大个数使得其中最大的数不超过最小的数P倍. trick: 测试点5会爆int,因为P太大了.. ...

  3. PAT 甲级 1051 Pop Sequence (25 分)(模拟栈,较简单)

    1051 Pop Sequence (25 分)   Given a stack which can keep M numbers at most. Push N numbers in the ord ...

  4. PAT Advanced 1020 Tree Traversals (25 分)

    1020 Tree Traversals (25 分)   Suppose that all the keys in a binary tree are distinct positive integ ...

  5. 1085. Perfect Sequence (25) -二分查找

    题目如下: Given a sequence of positive integers and another positive integer p. The sequence is said to ...

  6. PAT 甲级 1085 Perfect Sequence

    https://pintia.cn/problem-sets/994805342720868352/problems/994805381845336064 Given a sequence of po ...

  7. PAT (Advanced Level) 1085. Perfect Sequence (25)

    可以用双指针(尺取法),也可以枚举起点,二分终点. #include<cstdio> #include<cstring> #include<cmath> #incl ...

  8. 1085. Perfect Sequence (25)

    the problem is from PAT,which website is http://pat.zju.edu.cn/contests/pat-a-practise/1085 At first ...

  9. PAT Advanced 1140 Look-and-say Sequence (20 分)

    Look-and-say sequence is a sequence of integers as the following: D, D1, D111, D113, D11231, D112213 ...

随机推荐

  1. 123-PHP类构造函数

    <?php class ren{ //定义人类 private $name; //定义成员属性 public function __construct($name){ //定义构造函数 $thi ...

  2. 068-PHP定义并输出数组

    <?php $arr=array(98,'hello',67,'A',85,NULL); //定义一个数组 echo "输出第一个元素:{$arr[0]}"; //输出数组的 ...

  3. 可并堆模板题-mergeable heap

    Description 有n个点,第i个点标号为i,有两种操作:0 x y 表示把x所在堆和y所在堆合并.1 x 表示询问x所在堆的最小权. Input 第一行两个整数n,m,表示有n个点m个操作. ...

  4. 留学论文Results部分英文写作句型整理

    本文分享曼切斯特大学全校语言项目负责人约翰·莫莱博士(Dr John Morley)给出的与结果介绍相关的句型,小编为大家整理了一下一共分为了11类,看完之后觉得非常有用,这里分享给大家,各位留学小伙 ...

  5. hdu 1257 最少拦截系统 求连续递减子序列个数 (理解二分)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  6. Windows 2000 栈溢出 利用异常

    当在一个函数(test)里面自定义了异常处理,如下: 那么在运行时,它会把自定义的异常处理函数MyExceptionhandler()的地址放入栈中(PUSH 004013CC) 然后把fs:[0]的 ...

  7. 史上最好用的idea激活方法

    最近idea老出现激活一段时间然后就让重新激活的情况,每次都网上搜索一大堆激活方法,各种网址被封,各种插件不能用.就通过朋友介绍搞到一种方式,目前对于2018版本和2019版本都能激活并且正常使用.不 ...

  8. Python属性和内建属性

    属性property 1. 私有属性添加getter和setter方法 class Money(object): def __init__(self): self.__money = 0 def ge ...

  9. maven的理解和使用

    一.maven是什么? maven是项目管理工具 二.maven为什么要用? 在做开发的时候常常会用到外部的工具包(jar包),这就需要你一个一个的去他们的官网下工具包,然后在项目里依赖他们,比较的麻 ...

  10. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring CGLlB动态代理

    JDK 动态代理使用起来非常简单,但是它也有一定的局限性,这是因为 JDK 动态代理必须要实现一个或多个接口,如果不希望实现接口,则可以使用 CGLIB 代理. CGLIB(Code Generati ...