首页 > 代码库 > poj3061 Subsequence
poj3061 Subsequence
Subsequence
POJ - 3061题目大意:
给定长度为n的整数数列,以及整数S。求出总和不小于S的连续子序列的长度的最小值。若解不存在,则输出0.
Sample Input
210 155 1 3 5 10 7 4 9 2 85 111 2 3 4 5
Sample Output
23
/* 求出前缀和,然后枚举区间起点 区间起点固定下来了之后,终点位置二分查找 不要忘了输出0的情况 */#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;#define maxn 100010int t,n,a[maxn],sum[maxn],s;int main(){ //freopen("Cola.txt","r",stdin); scanf("%d",&t); while(t--){ memset(a,0,sizeof(a)); memset(sum,0,sizeof(sum)); scanf("%d%d",&n,&s); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } if(sum[n]<s){printf("0\n");continue;} int ans=n; for(int i=1;i<=n;i++){//枚举起点 int l=i,r=n;//二分中点 while(l<=r){ int mid=(l+r)>>1; int now=sum[mid]-sum[i-1]; if(now>=s)r=mid-1,ans=min(ans,mid-i+1); else l=mid+1; } } printf("%d\n",ans); }}
/* 尺取法: 1.初始化s,t,sum 2.只要依然有sum<m,就不断将sum加a[t],并将t加1 3.如果(2)中无法满足sum>=m则终止。否则更新ans 4.将sum减去a[s],s加1然后回到2 像区间右移 */#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define maxn 100010int T,n,t,a[maxn],s,m,sum;int main(){ scanf("%d",&T); while(T--){ s=1;t=0; sum=0; bool flag=0; scanf("%d%d",&n,&m); int ans=n; for(int i=1;i<=n;i++)scanf("%d",&a[i]); while(1){ while(t<n&&sum<m) sum+=a[++t]; if(sum<m)break; ans=min(ans,t-s+1);flag=1; sum-=a[s];s++; } if(flag==0){printf("0\n");continue;} else printf("%d\n",ans); } return 0;}
poj3061 Subsequence
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。