1. 程式人生 > >取尺法(算法)

取尺法(算法)

cep iostream turn 判斷 規律 最短 tab class 左右

 1 /*常用的解題技巧:尺取法
 2  尺取法:顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對數組保存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力枚舉區間效率高很多,尤其是數據量大的
 3        時候,所以尺取法是一種高效的枚舉區間的方法,一般用於求取有一定限制的區間個數或最短的區間等等。當然任何技巧都存在其不足的地方,有些情況下尺取法不可行,無法得出正確答案。
 4        使用尺取法時應清楚以下四點:
 5  1、什麽情況下能使用尺取法?  
2、何時推進區間的端點?
3、如何推進區間的端點?
3、何時結束區間的枚舉?
6 尺取法通常適用於選取區間有一定規律,或者說所選取的區間有一定的變化趨勢的情況,通俗地說,在對所選取區間進行判斷之後,我們可以明確如何進一步有方向地推進區間端點以求解滿足條件的區間,如果已經判斷了目前所選取的區間,但卻無法確定所要求解的區間如何進一步 7 得到根據其端點得到,那麽尺取法便是不可行的。首先,明確題目所需要求解的量之後,區間左右端點一般從最整個數組的起點開始,之後判斷區間是否符合條件在根據實際情況變化區間的端點求解答案。*/ 8 9 /*題目大意(poj 3061): 10 本題的意思是在保持原來順序不變的條件下,求得幾個連續元素之和大於S的最短序列長度。以第一組數據為例:
11 10 15 12 5 1 3 5 10 7 4 9 2 8 13 求第n項與前n項之和得:5 6 9 14 24 31 35 44 46 54 (記為a[i]) 14 t=a[i-1]-s,在序列中小於t的長度為n,a[i-1]到開始位置的長度為m,則在原始序列中由a[i-1]開始向前推長度為m-n+1的數8 2 9之和大於15,長度為3,依次往下推,求出最短長度。*/ 15 16 #include<iostream> 17 #include<cstdio> 18 #define
min(a,b) (a<b?a:b) 19 #define max(a,b) (a>b?a:b) 20 using namespace std; 21 const int MAXN=1e5; 22 int N,S; 23 int a[MAXN+1]; 24 int num; 25 void solve() { 26 int res=N+1; 27 int s=0,t=0,sum=0; 28 while(true) { 29 while(t<N&&sum<S) 30 sum+=a[t++]; 31 if(sum<S) 32 break; 33 res=min(res,t-s); 34 sum-=a[s++]; 35 } 36 if(res>N) 37 res=0; 38 cout<<res<<endl; 39 } 40 int main() { 41 cin>>num; 42 for(int tmp=1;tmp<=num;tmp++) { 43 int i=1; 44 cin>>N>>S; 45 for(i=1;i<=N;i++) 46 cin>>a[i]; 47 solve(); 48 } 49 return 0; 50 }

技術分享

時間 內存 結果 語言
79 596K Accepted C++



取尺法(算法)