PAT-乙-1030 1030 完美数列 (25 分)

在这里插入图片描述

代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {

	int N;
	long long p;
	scanf("%d %ld", &N, &p);

	vector<double> v;
	for(int i=0; i<N; i++) {
		double t;
		scanf("%lf", &t);
		v.push_back(t);
	}

	sort(v.begin(), v.end());

	int maxLen = 1;
	for(int i=v.size()-1; i>=0; i--) {
		if(i+1<=maxLen) {
			break;
		}
		double min = v.at(i)/p;
		int tmpLen = maxLen;
		for(int j=i-maxLen; j>=0; j--) {
			if(v.at(j)<min) {
				break;
			} else {
				tmpLen++;
			}
		}
		if(tmpLen>maxLen) {
			maxLen = tmpLen;
		}
	}

	printf("%d\n", maxLen);

	return 0;
}

注解

1、暴力法:排序后,从最后一个元素开始,依次找每个元素的完美数列所包含的元素个数。这样可得22分,案例4超时。
2、优化的方法:主要是下面这段代码

int maxLen = 1;
    	for(int i=v.size()-1; i>=0; i--) {
    		if(i+1<=maxLen) {
    			break;
    		}
    		double min = v.at(i)/p;
    		int tmpLen = maxLen;
    		for(int j=i-maxLen; j>=0; j--) {
    			if(v.at(j)<min) {
    				break;
    			} else {
    				tmpLen++;
    			}
    		}
    		if(tmpLen>maxLen) {
    			maxLen = tmpLen;
    		}
    	}

(1)如果当前元素所处位置,剩余的元素只有maxLen个,那么无论如何也不会超过当前的maxLen的结论,就可以终止循环,输出结果了。这样大大减少了无谓的判断次数。
(2)类似于字符串匹配KMP的思想,**若当前找到的maxLen为m,则下次不需要再从头开始比较,只需要从当前位置往前挪m个元素,看是否满足题目要求。**若满足,说明有可能达到更长的序列,则继续前移,否则不满足,继续试探下一个元素。这样就跳过了很多元素的比较,大大节约时间。

3、学到的语法:
(1)对vector排序:

#include <vector>
#include <algorithm>
vector<double> v;
sort(v.begin(), v.end());

结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhanggirlzhangboy/article/details/82942392
今日推荐