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,
- 数据类型需要仔细