poj 3061(二分 or 尺取法)
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 尺取法)的更多相关文章
- POJ 3061 Subsequence ( 尺取法)
题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...
- POJ 3061 Subsequence(尺取法)
题目链接: 传送门 Subsequence Time Limit: 1000MS Memory Limit: 65536K 题目描述 给定长度为n的数列整数以及整数S.求出总和不小于S的连续子 ...
- Atcoder Beginner Contest 155D(二分,尺取法,细节模拟)
二分,尺取法,细节模拟,尤其是要注意a[i]被计算到和a[i]成对的a[j]里时 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> ...
- POJ 3061 (二分+前缀和or尺取法)
题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...
- POJ 3061 Subsequence 二分或者尺取法
http://poj.org/problem?id=3061 题目大意: 给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. 思路: ...
- 题解报告:poj 3061 Subsequence(前缀+二分or尺取法)
Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...
- 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...
- poj 2566"Bound Found"(尺取法)
传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...
- POJ 2566 Bound Found(尺取法,前缀和)
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5207 Accepted: 1667 Spe ...
随机推荐
- python基础学习笔记(五)
字符串基本操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最小值和最大值)对字符串同样适用,前面已经讲述的这些操作.但是,请注意字符串都是不可变的. 字符串的方法: 字符串从str ...
- 第三次作业(1) Visual Studio程序安装过程和练习过程
Visual Studio程序安装过程和练习过程 第一步 首先要在网上找一个VS2013的安装包,之后我安装在D盘上,C盘上也需要有5.2G空间,勾选相应的选项,才能继续安装. 安装的过程很漫长,接近 ...
- Java awt项目开发
通过Java awt 界面上的知识编写的扫雷游戏 代码中有详细的注解 package com.langsin.saolei; import java.awt.Color;import java.awt ...
- Python学习笔记(三)——条件语句、循环语句
注:需注意代码的缩进格式 注:需注意代码的缩进格式 注:需注意代码的缩进格式 Python 与其他语言最大的区别就是,Python 的代码块不使用大括号 {} 来控制类,函数以及其他逻辑判断.pyth ...
- JWT验证
理解 JSON Web Token(JWT) 验证 JSON Web Token认证的操作指南 在本文中,我们将了解JSON Web Token的全部内容. 我们将从JWT的基本概念开始,然后查看其结 ...
- 在centos7虚拟机上挂载镜像,并设置yum源(包括遇到的问题)
挂载镜像方法很简单: mkdir /etc/a mount /dev/cdrom /etc/a 查看挂载情况 : df -h 修改yum源文件 : 先把 CentOS-Base.repo 文件名改一 ...
- python学习笔记七——字典
4.3 字典结构 字典是Python中重要的数据类型,字典的由“键-值”对组成的集合,字典中的“值”通过“键”来引用. 4.3.1 字典的创建 字典由一系列的“键-值”(key-value)对组成,“ ...
- codeforces586B
Laurenty and Shop CodeForces - 586B A little boy Laurenty has been playing his favourite game Nota f ...
- BZOJ2049[Sdoi2008]洞穴勘测——LCT
题目描述 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如 ...
- BZOJ1895Pku3580 supermemo——非旋转treap
题目描述 给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作: 1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D.例如对f1,2, 3,4,5g执行"AD ...