PAT-乙-1030 1030 完美數列 (25 分)
阿新 • • 發佈:2018-12-13
程式碼
#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());