标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11224 | Accepted: 4660 |
Description
Input
Output
Sample Input
2 10 15 5 1 3 5 10 7 4 9 2 8 5 11 1 2 3 4 5
Sample Output
2 3
尺取法做法:一直向前增加num[r],直到不能增加,再判断r-l,然后再一直向前减去num[l],然后判断是否小于s。一直循环。70+ms
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; const int N=100010; int list[N]; inline int Scan() { int res=0,ch,flag=0; if((ch=getchar())==‘-‘) flag=1; else if(ch>=‘0‘&&ch<=‘9‘) res=ch-‘0‘; while((ch=getchar())>=‘0‘&&ch<=‘9‘) res=res*10+ch-‘0‘; return flag?-res:res; } int main (void) { int t,n,s,i,j,temp,sum,ans; scanf("%d",&t); while (t--) { memset(list,0,sizeof(list)); scanf("%d%d",&n,&s); sum=0; for (i=1; i<=n; i++) { scanf("%d",&list[i]); } int l,r,dx; l=r=1; temp=0; dx=N; while (1) { while (r<=n&&temp<s)//r向前递增 { temp+=list[r++]; } if(temp<s) break; dx=min(r-l,dx); temp-=list[l++];//l向前递增 } if(dx==N)//特判 puts("0"); else printf("%d\n",dx); } return 0; }
二分查找做法:建立另外一个数组sufix来储存前缀和,然后题目变成了保证sufix[r]-sufix[l-1]>=S这样的条件下求r-l的最小值,显然r>=l。将这个式子移项得到sufix[r]>=S+sufix[l]。
就是说当遍历l的时候要使r最小,然后就用自带的lowerbound函数来求。
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; const int N=100010; int list[N]; int sufix[N]; int main (void) { ios::sync_with_stdio(false); int t,n,s,i,j,temp,sum,ans; cin>>t; while (t--) { cin>>n>>s; for (i=1; i<=n; i++) { cin>>list[i]; sufix[i]=sufix[i-1]+list[i]; } int dx=N; if(sufix[n]<s)//特判 { cout<<0<<endl; continue; } for (i=0; sufix[i]+s<=sufix[n]; i++)//由于是公式内为l-1,因此i要从0开始,即 { int t=lower_bound(sufix+i+1,sufix+n+1,s+sufix[i])-(sufix+i); dx=min(t,dx); } cout<<dx<<endl; } return 0; }
POJ——3061Subsequence(尺取法或二分查找)
标签:
原文地址:http://www.cnblogs.com/Blackops/p/5396532.html