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

解题过程的小记录,如有错误欢迎指出。

难度:三星(第一道二分算法题,二分模板要背一下 ,去背二分的STL容器)

题目分析

满足题中给出的条件:MAX<=MIN*p的数列被称为完美数列,给出一组数,要求组成完美数列的最长长度(或者说组成的数字的个数)

注意点

  1. 题中给出的数字的饭碗刚好卡在int的临界点附近,要注意类型的选择

我的解题过程

思路

本题属于从有序数列中找出一个值满足某一条件的类型题,用二分算法可以解决此类问题

  1. 把输入的数字进行递增排序
  2. 分析条件,为了避免int越界,可以把条件替换为t=MAX/p<=MIN,固定MAX即可找出满足条件的最小MIN值(找最小是为了让长度更大,在其中包括的数字最多)
  3. 如果扫描到的MAX的下标 减去 已经找出的最长长度为负,就没有必要再往下找

bug

做的过程中有翻书找模板,套了模板后一次过了

代码

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int n;
vector<int> num;

int comp(int n1, int n2) {
	return n1 < n2;
}

int solve(double t, int  left, int right) {
	while (left < right) {
		int mid = (left + right) / 2;
		if (num[mid] >= t) {
			right = mid;
		}
		else {
			left = mid + 1;
		}
	}
	return left;
}

int main()
{
	double p;
	cin >> n >> p;
	for (int i = 0; i < n; i++) {
		int nn;
		scanf("%d", &nn);
		num.push_back(nn);
	}
	sort(num.begin(), num.end(), comp);
	int ans = 0;
	for (int i = n - 1; i >= 0; i--) {
		double t = num[i] / p;
		int length = i - solve(t, 0, i) + 1;
		if (length > ans) ans = length;
		if (i - (length - 1) <= 0) break;
	}
	cout << ans;
    return 0;
}

dalao的代码

全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~

借鉴点

  1. 比较哪个长度最长可以采用ans=max(ans,length)的方法
  2. 二分算法在STL中直接有模板【呜呜呜太好了,不用背了,STL就是坠dior的】【用这个的话要记得返回的不是下标而是一个iterator,如果想要下标需要与begin()相减】
    可以适当参考以下两个链接
    C++中lower_bound函数和upper_bound函数.
    关于lower_bound( )和upper_bound( )的常见用法.
  3. 如果是简单的int排序可以直接sort(num.begin(),num.end()),不需要自己另外写
  4. 柳神的代码是没有采用二分的,直接双层嵌套循环找,不过保存了长度,每次子嵌套都加上长度后再判断,可能这就是循环嵌套没有超时的原因吧
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值