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++ |
时间: 2024-10-28 22:46:54