【PAT乙】1030 完美数列 (25分) 枚举

1030 完美数列 (25分)
给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:
输入第一行给出两个正整数 N 和 p,其中 N(≤10
​5
​​ )是输入的正整数的个数,p(≤10
​9
​​ )是给定的参数。第二行给出 N 个正整数,每个数不超过 10
​9
​​ 。

输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:
10 8
2 3 20 4 5 1 6 7 8 9

输出样例:
8


  • 第一遍5mins看完题,想速度快些,所以两边向中间靠近,一步得到最长序列
  • 但是总有部分答案过不了,写了15mins
//WA
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int a[maxn];
int main(){
	int n;  cin>>n;
	//double p;  cin>>p;
	int p; cin>>p;
	for(int i = 1; i <= n; i++)cin>>a[i];
	sort(a+1,a+n+1);
	int l = 1, r = n;
	while(l < r){
		/*
		double x = a[r]/a[l+1], y = a[r-1]/a[l];
		if(x<p){l++;break;}
		if(y<p){r--;break;}
		if(x<y)l++;else r--;
		*/
		if(a[r]<p*a[l+1]){l++;break;}
		if(a[r-1]<p*a[l]){r--;break;}
		if(a[r]*a[l]<a[r-1]*a[l+1])l++;else r--;
	}
	if(l!=r)cout<<r-l+1;
	else cout<<'0';
	return 0;
}

  • 然后看了标程,模拟就能水,又花10mins写了个模拟
  • 结果不剪枝会TLE,没有longlong会WA。。又调了10mins
//AC
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
int main(){
	LL n, p; cin>>n>>p;
	vector<int>a(n);
	for(int i = 0;i < n; i++)cin>>a[i];
	sort(a.begin(),a.end());
	LL ans = 0;
	for(int i = 0; i < n; i++){
		for(int j = i+ans; j < n; j++){//+ans剪枝
			if(a[j]<=a[i]*p)//不用longlong会溢出
				ans = max(ans, (LL)j-i+1);
			else break;
		}
	}
	cout<<ans;
	return 0;
}


  • 一道题本来打算10mins,结果写了40多mins,而且还看了标程
  • 调试一道题要想清楚再写,不然回来写成本太高了。
  • 很多基础题其实模拟就好,不要想太多

  • 数据规模,1000ms是10 ^ 7(n ^ 2的复杂度是 5000),所以200ms用n ^ 2的复杂度n要小于1000,
  • 数据类型需要仔细
发布了519 篇原创文章 · 获赞 46 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/qq_33957603/article/details/104483951