题目

给定⼀个正整数数列,和正整数p,设这个数列中的最⼤值是M,最⼩值是m,如果M <= m * p,则称这个数列是完美数列。现在给定参数p和⼀些正整数,请你从中选择尽可能多的数构成⼀个完美数列。

输⼊格式:

输⼊第⼀⾏给出两个正整数N和p,其中N(<= 10^5)是输⼊的正整数的个数,p(<= 10^9)是给定的参数。第⼆⾏给出N个正整数,每个数不超过109。

输出格式:

在⼀⾏中输出最多可以选择多少个数可以⽤它们组成⼀个完美数列。

输⼊样例:

10 8

2 3 20 4 5 1 6 7 8 9

输出样例:

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 Basic 完美数列(25) [two pointers]的更多相关文章

  1. PAT 1030. 完美数列(25)

    给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列. 现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列. ...

  2. PAT (Basic Level) Practise (中文)-1030. 完美数列(25)

    PAT (Basic Level) Practise (中文)-1030. 完美数列(25)   http://www.patest.cn/contests/pat-b-practise/1030 给 ...

  3. PAT乙级 1030. 完美数列(25)

    1030. 完美数列(25) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定一个正整数数列,和正整数p,设这 ...

  4. PAT 乙级1030 完美数列(25) C++版

    1030. 完美数列(25) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定一个正整数数列,和正整数p,设这 ...

  5. PAT-乙级-1030. 完美数列(25)

    1030. 完美数列(25) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定一个正整数数列,和正整数p,设这 ...

  6. PAT Basic 1030 完美数列 (25 分)

    给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格 ...

  7. PAT (Basic Level) Practice (中文)1030 完美数列 (25 分) (有点意思)

    给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格 ...

  8. PAT B1030 完美数列 (25 分)

    给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格 ...

  9. 牛客网PAT练兵场-完美数列

    题目地址:https://www.nowcoder.com/pat/6/problem/4056 题解:先将a数组进行排序,第一次按题意M<=n*p;n=a[0]时,M最大为J(如下图),然后n ...

随机推荐

  1. 如何为 .NET Core 安装本地化的 IntelliSense 文件

    在.Net Core 2.x 版本,Microsoft 官方没有提供 .Net Core 正式版的多语言安装包.因此,我们在用.Net Core 2.x 版本作为框架目标编写代码时,智能提成是英文的. ...

  2. nui UI 具有右键属性的菜单树

    参考示例:树右键菜单                 一:创建ContextMenu     <ul id="treeMenu" class="nui-contex ...

  3. OpenCV3 Ref SVM : cv::ml::SVM Class Reference

    OpenCV3  Ref SVM : cv::ml::SVM Class Reference OpenCV2: #include <opencv2/core/core.hpp>#inclu ...

  4. 读书笔记 - js高级程序设计 - 第八章 BOM

      BOM的核心对象是window 它表示浏览器的一个实例,在浏览器中,window对象有双重角色,它既是通过js访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象,这意味着在网 ...

  5. BZOJ 4901 [CTSC2017]网络

    题解: 只会O(n log^2 n) O(n log n)先留坑 不开long long 0 分!!!! #include<iostream> #include<cstdio> ...

  6. OFD系列软件说明(免费试用、QQ交流群:877371250)

    前言 OFD是一个版式文档格式.所谓版式文档格式是版面呈现效果固定的电子文档格式. 我们今天接触到最多的版式文档就是国际通用的PDF. 国内的就是由工业和信息化部软件司牵头中国电子技术标准化研究院成立 ...

  7. Java语言学习总结 扩展篇 DateFormat类

    DateFormat类 java.text .DateFormat 是 日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换:也就是可以在Date对象与String对象之间进 ...

  8. 一小时搞定Eureka

    一.什么是Eureka Eureka是Netflix公司开源的产品,它是一种基于REST( Representational State Transfer )的服务,主要用于AWS云. Eureka提 ...

  9. 吴裕雄--天生自然 PHP开发学习:常量

    <?php // 区分大小写的常量名 define("GREETING", "欢迎访问 Runoob.com"); echo GREETING; // 输 ...

  10. UML-迭代2:更多模式

    1.之前的初始阶段+细化阶段中的迭代1讲述的是广泛使用的基本分析和对象设计技术.而迭代2中,案例研究只强调: 对象设计和模式: 1).基本对象设计(基于职责和GRASP) 2).使用模式来创建稳固的设 ...