PAT甲级刷题之路——A1085 Perfect Sequence

原题如下

在这里插入图片描述
在这里插入图片描述

题目大意

给出一个整数组成的序列和另外一个整数p,认为如果 M ≤ m × p M\leq m\times p Mm×p则认为该序列为一个完美序列,其中M和m分别指序列中的最大最小值。
给出一个序列和参数p,找出能使其包含最多数字的完美子序列。
输入:
第一行包含序列长度N和参数p;
后面一行是序列
输出:
输出满足题意的完美子序列的长度。

自己的想法

用一个结构体左半边存储该数、该数为最小数是可以允许的最大数、自己作为最小数那么最大数和自己的长度。

答案反馈

自己的方法好蠢啊

错误1

在这里插入图片描述
没有考虑原序列最大值也小于最小值*p;

错误2

在这里插入图片描述
整数*p可能超过int型,故需要用long long型存储。(因为这个错了不止一次了!!!重点关注!!!

AC

在这里插入图片描述

AC代码

我的代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<set>
#include<queue>
#include<map>
#include<stack>
using namespace std;
const int maxn = 100010;
struct sequence {
	long long data, index;
	int kk = 0;
}seq[maxn];
bool cmp1(sequence &a,sequence &b) {
	return a.data < b.data;
}
bool cmp2(sequence &a, sequence &b) {
	return a.kk > b.kk;
}
int main() {
	int n, p;
	cin >> n >> p;
	for (int i = 0; i < n; i++) {
		cin >> seq[i].data;
	}
	sort(seq, seq + n, cmp1);
	if (n == 0) {
		cout << '0' << endl;
	}
	else if (n==1) {
		cout << '1'<< endl;
	}
	else {
		int start;
		for (int i = 0; i < n; i++) {
			if (seq[i].data > (seq[0].data*p)) {
				start = i-1; seq[0].index = i-1; seq[0].kk = seq[0].index - 0+1;
				//cout << seq[0].index << ' ' <<seq[seq[0].index].data<<' '<< seq[0].kk << endl;
				break;
			}
			else if (i == n - 1) {
				start = i; seq[0].index = i; seq[0].kk = seq[0].index - 0 + 1;
			}
		}
		for (int i = 1; i < start; i++) {
			for (int j = seq[i - 1].index; j < n; j++) {
				if (seq[i].data*p < seq[j].data) {
					//cout << "***" << endl;
					//cout << seq[i].data << ' ' << j<<' '<<seq[j].data << endl;
					seq[i].index = j - 1; seq[i].kk = seq[i].index - i+1;
					//cout << i << ' ' << seq[i].index << ' '<<seq[i].kk << endl;
					break;
				}
				else if (j == n - 1) {
					seq[i].index = j ; seq[i].kk = seq[i].index - i + 1;
				}
			}
		}
		sort(seq, seq + n, cmp2);
		cout << seq[0].kk << endl;
	}
	return 0;
}
优秀思路学习

既然自己的代码如此蹩脚,那么肯定要学习下优秀大佬的代码思路啦~
又要搬出柳神了->柳神A1085传送门
そっか!!!
其实从i=1-n之间,每一次只要从之间保留的最长长度result+i开始计算就可以了,一遍替换result,最后输出!
用upper_round会更快

upper_round(begin,end,num);
//指从数组的begin位置开始到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,若不存在则返回end。
//通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
//lower_round用法类似

结语

当样例过不了的时候,重点关注数据类型!!!考虑超过int型的可能性!!!但也不能无脑long long型!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值