1. 程式人生 > >【尺取】HDU Problem Killer

【尺取】HDU Problem Killer

spa open problem math div queue ios blog 整數

acm.hdu.edu.cn/showproblem.php?pid=5328

【題意】

給定一個長度為n的正整數序列,選出一個連續子序列,這個子序列是等差數列或者等比數列,問這樣的連續子序列最長是多少?

【思路】

尺取,用來解決這樣的問題:需要在給的一組數據中找到不大於某一個上限的“最優連續子序列”

分別用雙指針找最長的等差數列和等比數列,找最大值就可以了。

註意a 或者 a b既是等差數列,又是等比數列。

【Accepted】

技術分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4
#include <vector> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <queue> 9 #include <deque> 10 #include <stack> 11 #include <string> 12 #include <bitset> 13 #include <ctime> 14 #include<algorithm> 15 #include<cstring> 16
using namespace std; 17 typedef long long ll; 18 int n; 19 const int maxn=1e6+2; 20 int a[maxn]; 21 int ans; 22 int AP() 23 { 24 int l=0; 25 int r=1; 26 int add=a[r]-a[l]; 27 int res=2; 28 while(l<n && r<n) 29 { 30 while(r<n && a[r]-a[r-1]==add)
31 { 32 r++; 33 } 34 res=max(res,r-l); 35 l=r-1; 36 add=a[r]-a[l]; 37 } 38 return res; 39 } 40 int GP() 41 { 42 int l=0; 43 int r=1; 44 double q=(double)a[r]/(double)a[l]; 45 int res=0; 46 while(l<n && r<n) 47 { 48 while(r<n && (double)a[r]/(double)a[r-1]==q) 49 { 50 r++; 51 } 52 res=max(res,r-l); 53 l=r-1; 54 q=(double)a[r]/(double)a[l]; 55 } 56 return res; 57 } 58 int main() 59 { 60 int T; 61 scanf("%d",&T); 62 while(T--) 63 { 64 scanf("%d",&n); 65 for(int i=0;i<n;i++) 66 { 67 scanf("%d",&a[i]); 68 } 69 if(n<=2) 70 { 71 printf("%d\n",n); 72 continue; 73 } 74 ans=2; 75 ans=max(ans,AP()); 76 ans=max(ans,GP()); 77 printf("%d\n",ans); 78 } 79 return 0; 80 }
View Code

【尺取】HDU Problem Killer