1030 完美数列
分数 25
作者 CAO, Peng
单位 Google
给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤m**p,则称这个数列是完美数列。
现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109。
输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入样例:
10 8
2 3 20 4 5 1 6 7 8 9
输出样例:
8
代码长度限制
16 KB
时间限制
200 ms
内存限制
64 MB
代码思路:
- 用数组接收,并从小到大排序
- 利用双层循环进行遍历,记录每次符合条件的最大元素个数
- 优化:内层循环开始可以从
(本次下标+上次最多个数)
开始,可以节省时间 - 注意:最后一个检查点要用
longlong类型
代码实现:
#include<iostream>
#include<algorithm>
using namespace std;
int* arr = new int[100010];
int main()
{
// 读取输入的整数 N 和倍数 p
long long N, p;
cin >> N >> p;
// 读取数组元素
for (int i = 0; i < N; i++)
{
cin >> arr[i];
}
// 将数组元素进行排序
sort(arr, arr + N);
int sum = 0; // 计数器,记录当前子序列的长度
int ans = 0; // 最大子序列的长度
int temp = 0; // 临时变量,记录上一个满足条件的子序列的长度
for (int i = 0; i < N; i++)
{
int m = arr[i]; // 当前元素
sum = 0;
// 在当前位置开始,遍历数组,找出满足条件的子序列长度
for (int k = i+temp; k < N; k++)
{
if (arr[k] <= m * p)
sum++;
else
break;
}
// 更新最大子序列的长度
if (ans < sum+temp)
{
temp = sum + temp;
ans = temp;
}
}
// 输出结果
cout << ans;
return 0;
}