POJ-3061 Subsequence 二分或尺取

题面

题意:给你一个长度为n(n<100000)的数组,让你找到一个最短的连续子序列,使得子序列的和>=m  (m<1e9)

题解: 1 显然我们我们可以二分答案,然后利用前缀和判断是否可行,这样是O(nlgn)的   注意没有答案 ans输出0

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 int T,n,m,a[100005],l,r,ans;
 7 int check(int x)
 8 {
 9     for (int i=1;i<=n-x+1;i++)
10     {
11         if (a[i+x-1]-a[i-1]>=m) return 1;
12      }
13      return 0;
14 }
15 int main()
16 {
17     scanf("%d",&T);
18     while (T--)
19     {
20         memset(a,0,sizeof(a));
21         scanf("%d%d",&n,&m);
22         for (int i=1;i<=n;i++) 
23         {
24             scanf("%d",&a[i]);
25             a[i]+=a[i-1]; 
26         }
27         l=1;r=n;ans=0;
28         while (l<=r)
29         {
30             int mid=(l+r)/2;
31             if (check(mid)) 
32             {
33                 ans=mid;
34                 r=mid-1;
35             }else l=mid+1;
36         }
37         printf("%d\n",ans);
38     } 
39  } 

猜你喜欢

转载自www.cnblogs.com/qywhy/p/9691705.html