PAT乙级1030

尺取法

尺取法通常是指对数组保存一对下表(起点,终点),然后根据实际情况交替推进两个端点直接得出答案的方法,这种操作很像是尺蠖(日文中称为尺取虫)爬行的方式故得名。

(以上文字摘自挑战程序设计竞赛第2版)

Codeforces中显示它的算法名称叫做"two pointers". 直译成中文的话叫双指针法. 怎么说呢……做到提高组之后,很多oier仅仅是觉得好像有这么一个两个指针从左到右扫一遍的算法存在,却不知道它的名字.(其实是因为大佬们根本没把它当个算法) 这个算法不是很难,却很有意思. 尺取法是一种比较基础的算法,一般用来解决具有单调性的区间问题. 当然,说到单调性,大家都会想到二分. 尺取法能做的题,有很大的概率也可以用二分解决,不过尺取和二分的复杂度在不同的题目中往往是不同的. 所以尺取法的题大概也是找到可二分性然后优化之. 我想不到类比尺取法的实际问题,所以我只能给了很多例题. 大家如果有的话可以告诉我,我将非常感谢. 维护两个指针 l,r ,每次确定区间的左端点,让 r 不断向右移动,直到满足条件停下,维护一下答案,直到 r>n 或者其它情况(视题目而定). 而实际中很多算法都要用到尺取法来辅助或者优化计算,尤其是分治算法.

(摘自洛谷日报第73期,原文章链接:https://baijiahao.baidu.com/s?id=1615129382322508344&wfr=spider&for=pc,原文作者:Fuko_Ibuki)

这个题目先对数组进行排序,这个问题就成为了具有单调性的区间问题,定义两个指针head,tail,tail取便所有数组,判断a[head]<=p*a[tail](不难发现,此时a[head]是完美数列中的最小值,a[tail]是最大值),符合条件就更新最大长度,如果不符合就让头指针++

参考sxy大佬的代码

#include 
#include 
#include 
#include 
using namespace std;
long long a[100001];

int main()
{
	int n,p,i;
	cin>>n>>p;
	for(i=0;i>a[i];
	sort(a,a+n);
	int head=0,tail=0,ans=1;
	while(tailp*a[head])
		++head;
	}
	cout<

 

你可能感兴趣的:(模拟)