zoukankan      html  css  js  c++  java
  • 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  } 
    Anderyi!
  • 相关阅读:
    设计模式-17-迭代器
    设计模式-16-备忘录
    微服务架构设计
    数据库拆分案例
    生成多个git ssh密钥
    分布式数据中间件TDDL、Amoeba、Cobar、MyCAT架构比较
    maven工程 java 实现文件上传 SSM ajax异步请求上传
    MySQL的分区、分表、集群
    Redis实现分布式锁原理与实现分析
    关于消息队列的使用
  • 原文地址:https://www.cnblogs.com/qywhy/p/9691705.html
Copyright © 2011-2022 走看看