传送门:Problem 3061

https://www.cnblogs.com/violet-acmer/p/9793209.html

马上就要去上课了,先献上二分AC代码,其余的有空再补

题意:

  给定长度为 n 的整数数列 a[0,1,2,........,n]以及整数 S。

  求出总和不小于 S 的连续子序列的长度的最小值。

  如果解不存在,则输出 0。

题解:

  1、二分

    由于所有的元素都大于 0 ,所以数组a[ ] 的前缀和sum[ ]为递增的序列,满足二分的条件。

    首先确定子序列的起点为start(start的可能取值为 1,2,......,n)。

    假设区间[start,end]是以start为子序列起点的最小区间,则需要满足 sum[end]-sum[start-1] >= S,而确定满足条件的最小的 end 用二分即可在O(longn)的时间完成。

    所以总的时间复杂度为 O(nlogn)

  2、尺取法

    相关说明:

      设以a[start]为子序列起点的总和最初大于S的连续子序列为a[start,......,end],此时 res = end-start+1;

    (1):end++,找到最大的 k ,使得在去除当前子序列的前 k 个数后依旧满足 sum[end]-sum[start-1 + k] >= S,并判断是否需要更新 res。

    (2):重复(2)过程,直到 end > n 为止。

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mem(a,b) (memset(a,b,sizeof(a)))
const int maxn=1e5+; int N,S;
int a[maxn];
int sum[maxn];
int binarySearch(int val)
{
int l=,r=N+;
while(r-l > )
{
int mid=l+((r-l)>>);
if(sum[mid] >= val)
r=mid;
else
l=mid;
}
return r;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
mem(sum,);
scanf("%d%d",&N,&S);
int res=;
for(int i=;i <= N;++i)
{
scanf("%d",a+i);
sum[i] += sum[i-]+a[i];
}
for(int s=;s <= N;++s)
{
int t=binarySearch(sum[s-]+S);
if(t != N+)
res=(res== || (t-s+)<res ? t-s+:res);
}
printf("%d\n",res);
}
}

二分

 #include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define pb push
const int maxn=1e5+; int N,S;
int a[maxn];
queue<int >myqueue; int main()
{
int T;
scanf("%d",&T);
while(T--)
{
while(!myqueue.empty())
myqueue.pop();
scanf("%d%d",&N,&S);
for(int i=;i <= N;++i)
scanf("%d",a+i);
int end=;
int sum=;
int res=;
while(sum < S && end <= N)//先找到以1为序列起点的满足条件的最小的end
{
sum += a[end];
res++;
myqueue.pb(a[end++]);
}
if(sum >= S)
{
while(sum-myqueue.front() >= S)//找到满足条件的当前最小的范围
{
sum -= myqueue.front();
myqueue.pop();
res--;
}
while(end <= N)
{
myqueue.pb(a[end]);
sum += a[end++];
while(sum-myqueue.front() >= S)//步骤(2)
{
sum -= myqueue.front();
myqueue.pop();
}
res= res > myqueue.size() ? myqueue.size():res;//判断是否更新 res
}
}
else
res=;
printf("%d\n",res);
}
}
 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+; int N,S;
int a[maxn]; int Solve()
{
int start=,end=;
int res=;
int sum=;
while()
{
while(end <= N && sum < S)
sum += a[end++];
if(sum < S)
break;
res=(res == || (end-start) < res ? end-start:res);
sum -= a[start++];
}
return res;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&S);
for(int i=;i <= N;++i)
scanf("%d",a+i);
printf("%d\n",Solve());
}
}

尺取法&挑战程序设计竞赛

poj 3061(二分 or 尺取法)的更多相关文章

  1. POJ 3061 Subsequence ( 尺取法)

    题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...

  2. POJ 3061 Subsequence(尺取法)

    题目链接: 传送门 Subsequence Time Limit: 1000MS     Memory Limit: 65536K 题目描述 给定长度为n的数列整数以及整数S.求出总和不小于S的连续子 ...

  3. Atcoder Beginner Contest 155D(二分,尺取法,细节模拟)

    二分,尺取法,细节模拟,尤其是要注意a[i]被计算到和a[i]成对的a[j]里时 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> ...

  4. POJ 3061 (二分+前缀和or尺取法)

    题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...

  5. POJ 3061 Subsequence 二分或者尺取法

    http://poj.org/problem?id=3061 题目大意: 给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. 思路: ...

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

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  7. 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers

    题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...

  8. poj 2566"Bound Found"(尺取法)

    传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...

  9. POJ 2566 Bound Found(尺取法,前缀和)

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5207   Accepted: 1667   Spe ...

随机推荐

  1. keepalived概述

    一.HA集群中的相关术语 1.节点(node) 运行HA进程的一个独立主机,称为节点,节点是HA的核心组成部分,每个节点上运行着操作系统和高可用软件服务,在高可用集群中,节点有主次之分,分别称之为主节 ...

  2. C_数据结构_走迷宫

    #include <stdio.h> #include <conio.h> #include <windows.h> #include <time.h> ...

  3. Android中Json数据读取与创建的方法

    转自:http://www.jb51.net/article/70875.htm 首先介绍下JSON的定义,JSON是JavaScript Object Notation的缩写. 一种轻量级的数据交换 ...

  4. Maximal Binary Matrix CodeForces - 803A (贪心+实现)

    题目链接 题意有点坑: 给你一个N*N的矩阵,让你填入K个1,使之整个矩阵关于左上到右下的对角线对称,并且这个要求这个矩阵的字典序最大. 对矩阵的字典序的定义是从每一行的第一个元素开始比较,大着为字典 ...

  5. maven配置私服

    1先配置maven的配置文件 2在项目的pom.xml文件增加 <distributionManagement> <repository> <id>nexus-re ...

  6. 软件工程(GZSD2015) 第三次作业提交进度

    第三次作业题目请查看这里:软件工程(GZSD2015)第三次作业 开始进入第三次作业提交进度记录中,童鞋们,虚位以待哈... 2015年4月19号 徐镇.尚清丽,C语言 2015年4月21号 毛涛.徐 ...

  7. [2017BUAA软件工程]第0次个人作业

    第一部分: 结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢? 有时候我也问自己这个问题,是因为认识的人中有人从事这个工作并且做得很好而产生了艳羡?是因为家长一次次催逼,想 ...

  8. Selenium IDE 宏 试用 一例

    本质是宏(Macro)理念 Marco概念的广泛应用: 1.Office的Excel里的任何操作的 可以都可以用VBA编程记录下宏,然后把记录的宏,可以回放.当然也可以生成代码,比如给Excel设置单 ...

  9. Oracle 通过触发器实现ID自增

    Oracle不像Mysql,SQLServer能够直接设置ID自增,但是可以通过触发器实现ID自增. 1 创建测试表 create table t_goods(id number primary ke ...

  10. 服务器RAID设置以及简单理解

    备注: 适用于测试环境,生产环境暂时未验证 1. RAID种类 最高性能的RAID0 完全拆分所有的IO 不进行校验 但是单盘损坏, 数据完全丢失 最高损耗的RAID1 损失一半的存储容量, 做镜像, ...