POJ-3061 Subsequence 二分或尺取

Posted qywhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",ans);
38     } 
39  } 

  2 还是一道尺取的裸题,先取前x个数(r++),直到大于m,此时减去该区间最前面的一个数(收缩 l++),再次判断是否大于S,重复操作,直至r==n或取得的区间无法大于S 停止

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 int sum,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++) scanf("%d",&a[i]);
23         
24         ans=n+1;l=1;r=1;sum=0;
25         while (1)
26         {
27             while (r<=n && sum<m)
28             {
29                 sum+=a[r];
30                 r++;
31             }
32             if (sum<m) break;else
33             {
34                 ans=min(ans,r-l);
35                 sum-=a[l];
36                 l++;
37             } 
38         }
39         if (ans!=n+1) printf("%d
",ans);else printf("0
");
40     } 
41  } 

 

以上是关于POJ-3061 Subsequence 二分或尺取的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3061 Subsequence (二分||尺取法)

题解报告:poj 3061 Subsequence(二分前缀法or尺取法)

POJ 3061 Subsequence ( 二分 || 尺取法 )

poj3061 Subsequence

Subsequence(POJ 3061)

Subsequence POJ - 3061