给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。
现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109。
10 8
2 3 20 4 5 1 6 7 8 9
输出样式:8
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
#include<stdio.h>
#include<stdlib.h>
int findmin(int a, int b) {
return a > b ?b :a ;
}
void merge(int arr[], int L, int M, int R) {
int help[50] = { 0 };
int p1 = L;
int p2 = M + 1;
int i = L;
while (p1 <= M && p2 <= R) {
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
int j = L;
while (j <= R) {
arr[j] = help[j];
j++;
}
}
//归并算法迭代版
int process2(int arr[], int L, int R) {
int len = R - L + 1;
if (arr==NULL||len<2){ return 0; }
//规定步长step初始步长为1
int step = 1;
while (step<len)//步长不可以大于数组长度
{
int l = 0;
while (l<len)//l是:当前左组的第一个位置
{
int m = l + step-1;
if (m >= len) { break; }//如果连右组前一位都大于len,跳出这个while循环,直接步长*2
int r = findmin(R, m + step);
merge(arr, l, m, r);
l = r + 1;
}
if (step>len/2) {
break;
}
step = step * 2;
}
return 0;
}
int main(void) {
int N = 0;
int p = 0;
int* arr = (int*)malloc(sizeof(int));
scanf("%d %d", &N, &p);
for (int i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}
process2(arr, 0, N - 1);
if (arr==NULL)
{
return 0;
}
int ma = arr[0];
int max = ma * p;
int j = 0;
for (int i = 0; i < N; i++)
{
if (arr[i] <= max) {
j++;
}
}
printf("%d", j);
}