PAT B1030/A1085 完美数列

题目
这道题乍一看,直接两个for循环就可以解决,但仔细一想,10^5的规模,很明显是会超时的,所以有什么能缩减复杂度的方法呢?因为确定了m后,就是查找相应的M,很自然的想到二分查找,这样可以降低复杂度为O(nlongn),可以通过自己写binarysearch()的方法找M,但实际上algorithm头文件下有一个upper_bound()函数可以使用,并且十分方便的找到M,问题到这里看似已经解决了,但真的submit的时候又出问题了。
问题就在a[i]和p都最大是10^9,两者相乘后的结果int绝对溢出了,所以想到用long long,但基础不扎实的人,比如我,就会直接mp=a[i]*p; 再将mp代入函数中,自以为没有问题,但提交后,最后一个测试点就是过不去,想了很久都没能解决,最后在同学(小飞侠)的提醒下想到,mp=a[i]*p; 该语句右边不强制类型转换在赋值前就已经溢出了,再往函数里加必然还是错。
除了用二分查找的方法外,还有第二种方法,就是two pointers,该方法更为简单,在下面代码的注释中给出了,这么简单的方法当然是找的题解中看到了_

using namespace std;
#include<bits/stdc++.h>
int a[100010];

int main(){
	int n,p,i,j;
	scanf("%d%d",&n,&p);
	for(i=0;i<n;i++) scanf("%d",&a[i]);
//	long long mp;
	sort(a,a+n);
	int ma=1;
	for(i=0;i<n;i++){
//		mp=(long long)a[i]*p;//一定要在右边强制类型转换否则赋值前就已经出错了 
		j=upper_bound(a+i+1,a+n,(long long)a[i]*p)-a;//upper_bound为自带函数 
		ma=max(ma,j-i);
	}
	/*two pointers
	int i=0,j=0,ma=1;
	while(i<n && j<n){
		while(j<n && a[j]<=(long long)a[i]*p){
			ma=max(ma,j-i+1);
			j++;
		}
		i++;
	}
	*/	
	printf("%d",ma);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值