PAT乙级 1030 完美数列

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

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

输出格式:

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

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9

输出样例:

8

思路:

记录下最大值Max,从数组第一个开始,把每一个值都当做最小值m,看是否满足Max≤mp,满足则计数加一。

代码:

#include
int main(){
	long Max=0;
	int N;
	long series[100000],p;
	scanf("%d %ld",&N,&p);
	int cnt=N;
	for(int i=0;iseries[i]*p) --cnt;
	}
	printf("%d",cnt);
	return 0;
}

PAT乙级 1030 完美数列_第1张图片

遗留问题:

测试点4为什么无法通过呢?

第一次修改:

测试点四的错误大概是因为忽略了这样一个问题:包含最大数的完美数列的正整数个数可能没有以次大数为最大数的完美数列的正整数个数多。于是重新做了一次,这次先使用选择排序对数列进行了降序排序,然后检测每一个完美数列包含的正整数的个数,并取个数最多的那一个。

代码:

#include
int main(){
	int N,sign=1,cnt;
	long series[100000],p;
	scanf("%d %ld",&N,&p);
	for(int i=0;i

PAT乙级 1030 完美数列_第2张图片

遗留问题:

测试点4运行超时。

第二次修改:

运行超时是因为选择排序的时间复杂度为O(n2),改用快速排序,其时间复杂度为O(N*logN)。
这里是大神对快速排序的讲解:https://blog.csdn.net/MoreWindows/article/details/6684558

代码:

#include
void quick_sort(long s[], int l, int r)
{
    if(l=x) // 从左向右找第一个大于等于x的数
				i++;  
            if(i

PAT乙级 1030 完美数列_第3张图片

遗留问题:

测试点4依然超时。

第三次修改:

这次参考网友的代码,改进了统计完美数列包含正整数的个数的方法,每次开始查找的范围随着cnt(完美数列元素个数)的值增大不断缩减。

代码:

#include
void quick_sort(long s[],int l,int r)
{
    if(l=x) // 从右向左找第一个小于x的数
				j--;  
            if(i=series[j]) ++cnt;
			else break;
		} 
	}
	printf("%d",cnt);
	return 0;
}

PAT乙级 1030 完美数列_第4张图片

你可能感兴趣的:(C,PAT乙级试题)