PAT 1030 完美數列(25)


題目

/*
 1030. 完美數列(25)
 
 給定一個正整數數列,和正整數p,設這個數列中的最大值是M,最小值是m,如果M <= m * p,則稱這個數列是完美數列。
 
 現在給定參數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
 */

思路

// 考慮過程
// m[i]*p - M[j] >= 0 j-i 盡量大

// 123456789*p m  小->大
// 123456789   M

//思路: 先排序,再找最大值

代碼

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main(){
	int n;
	float p;
	int seq[100005];
	int res = 1; // 這里初始化為0會造成后面數組越界,開始的算法不會有這個問題,改變算法后此處不改導致錯誤產生
	cin >> n >> p;
	
	
	for (int i = 0; i < n; ++i) {
		scanf("%d",&seq[i]);
	}
	
	sort(seq, seq+n);

//	 這個算法是不斷縮小范圍,每次都需要從最大開始進行縮小。這個算法會導致超時
//	for (int i = 0; i < n; ++i) {
//		for (int j = n-1; j > i + res - 1; --j) {
//			if (seq[j] <= product[i]) {
//				if (j - i + 1 > res) {
//					res = j - i + 1;
//				}
//				break;
//			}
//		}
//	}
	
	//	這個算法是不斷擴大范圍,每次擴大的范圍越來越小,因為滿足條件的值是在小范圍內波動的。
	for (int i = 0; i < n; ++i) {
		for (int j = i+res-1; j < n;++j){
			if (seq[j] <= seq[i]*p) {
				if (j-i+1 > res) {
					res = j - i + 1;
				}
			}else{
				break;
			}
			
		}
	}
	
	printf("%d\n",res);
	
	
}

過程資料

注意:

  1. 純整數運算在數據較大時容易越界導致結果錯誤。應當將其轉化為浮點運算。在此題中即把 p 定義為浮點數。
  2. 改變算法后,使用的變量的初值可能會需要改變,要對變量的邊界改變情況敏感。例如此題中的res初值。

測試點:

  1. 數組越界導致1、3測試點錯誤。
  2. 最后一個測試點是大數,m*p 會超出整數范圍,不能使用整數進行計算。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM