POJ_3061 && POJ_3320 (尺取法)

Subsequence

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9587   Accepted: 3855

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements
of the sequence, the sum of which is greater than or equal to S.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case,
separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample Output

2
3

题意:给定长度为n的数列整数A0,A1,A2……An-1以及整数S。求出总和不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。

分析:尺取法。只要sum<S,则一直往后加Ai;当sum>=S时,一直去掉前面已加的项。

题目链接:http://poj.org/problem?id=3061

代码清单:

#include<iostream>
#include<algorithm>
using namespace std;

const int maxn = 100000 + 5;
int N,S,T;
int a[maxn];

void input(){
  cin>>N>>S;
  for(int i=0;i<N;i++) cin>>a[i];
}

//尺取法
void solve(){
    int sum=0,Start=0,End=0,ans=maxn;
    while(true){
        while(End<N&&sum<S){ //当总和sum<S时,一直往后加
            sum+=a[End];
            End++;
        }
        if(sum<S) break;
        while(Start<N&&sum>=S){ //当总和sum>=S时,一直去掉前面的项
            sum-=a[Start];
            Start++;
        }
        ans=min(ans,End-Start+1);
    }
    if(ans>N) cout<<"0"<<endl;
    else cout<<ans<<endl;
}

int main(){
    cin>>T;
    while(T--){
        input();
        solve();
    }return 0;
}

Jessica‘s Reading Problem

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7838   Accepted: 2507

Description

Jessica‘s a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that text
book, like other authors, is extremely fussy about the ideas, thus some ideas are covered more than once. Jessica think if she managed to read each idea at least once, she can pass the exam. She decides to read only one contiguous part of the book which contains
all ideas covered by the entire book. And of course, the sub-book should be as thin as possible.

A very hard-working boy had manually indexed for her each page of Jessica‘s text-book with what idea each page is about and thus made a big progress for his courtship. Here you come in to save your skin: given the index, help Jessica decide which contiguous
part she should read. For convenience, each idea has been coded with an ID, which is a non-negative integer.

Input

The first line of input is an integer P (1 ≤ P ≤ 1000000), which is the number of pages of Jessica‘s text-book. The second line contains
P non-negative integers describing what idea each page is about. The first integer is what the first page is about, the second integer is what the second page is about, and so on. You may assume all integers that appear can fit well in the signed 32-bit
integer type.

Output

Output one line: the number of pages of the shortest contiguous part of the book which contains all ideals covered in the book.

Sample Input

5
1 8 8 8 1

Sample Output

2

题意:为了准备考试,Jessica开始读一本很厚的课本。要想通过考试,必须把课本中所有的知识点都掌握。这本书共有P(1<=P<=10^6)页,第i页恰好有一个知识点Ai(每个知识点都有一个整数编号)。全书中同一个知识点可能会被多次提到,所以她希望通过阅读其中连续的一些页把所有的知识点都覆盖到。给定每页写到的知识点,请求出要阅读的最少页数。

分析:尺取法。我们可以先把种类数算出来(利用set集合),然后,假设在区间[s,t]已经覆盖了所有的知识点,我们可以从s开始,把s取走后,那么页s上的知识点出现次数就要减一,如果此时这个知识点的出现次数为0了,那么,在同一个知识点出现之前,不停地将区间末尾t向后推进即可。

题目链接:http://poj.org/problem?id=3320

代码清单:

#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn = 1000000 + 5;

int p,a[maxn];
set<int>all;
map<int,int>m;

void input(){
    scanf("%d",&p);
    for(int i=0;i<p;i++){
        scanf("%d",&a[i]);
        all.insert(a[i]);
        m[a[i]]=0;
    }
}

void solve(){
    int Start=0,End=0,ans=maxn;
    int n=all.size(),sum=0;
    while(true){
        while(End<p&&sum<n){
            if(m[a[End]]==0){
                sum++;
            }
            m[a[End]]++;
            End++;
        }
        if(sum<n) break;
        ans=min(ans,End-Start);
        if(m[a[Start]]==1){
            sum--;
        }
        m[a[Start]]--;
        Start++;
    }
    printf("%d\n",ans);
}

int main(){
    input();
    solve();
    return 0;
}
时间: 2024-10-05 05:24:16

POJ_3061 && POJ_3320 (尺取法)的相关文章

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

hihocoder-1483区间价值 (二分+尺取法)

题目链接: 区间价值 给定n个数A1...An,小Ho想了解AL..AR中有多少对元素值相同.小Ho把这个数目定义为区间[L,R]的价值,用v[L,R]表示. 例如1 1 1 2 2这五个数所组成的区间的价值为4. 现在小Ho想知道在所有的的v[L,R](1 <= L <= R <= n)中,第k小的值是多少. Input 第一行一个数T(T<=10),表示数据组数. 对于每一组数据: 第一行两个数n,k(1<=n<=200,000,1<=k<=n*(n+1

【转】毛虫算法&mdash;&mdash;尺取法

转自http://www.myexception.cn/program/1839999.html 妹子满分~~~~ 毛毛虫算法--尺取法 有这么一类问题,需要在给的一组数据中找到不大于某一个上限的"最优连续子序列" 于是就有了这样一种方法,找这个子序列的过程很像毛毛虫爬行方式,我管它叫毛毛虫算法,比较流行的叫法是"尺取法". 喏,就像图里的妹纸一样~ 还是举个栗子: Poj3061 给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度 输入 n = 1

51nod1127(尺取法)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1127 题意:中文题诶- 思路:尺取法 维护一个队列,若当前队首的元素在后面出现了,那么我们就将其删除,若当前队列里含有26个字母,我们就记录其size. 取所有size里面的最小值就是我们要的答案... 代码: 1 #include <iostream> 2 #include <stdio.h> 3 #include <string>

BestCoder Round #86 二,三题题解(尺取法)

第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nnn 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后他计算出了所有相邻两数的差的绝对值的最大值. 他当然知道这个最大值会随着他删了的数改变而改变,所以他想知道假如全部数被删除的概率是相等的话,差的绝对值的最大值的期望是多少. 输入描述 第一行为一个正整数 T,表示数据组数. 每组数

POJ 3320 尺取法,Hash,map标记

1.POJ 3320 2.链接:http://poj.org/problem?id=3320 3.总结:尺取法,Hash,map标记 看书复习,p页书,一页有一个知识点,连续看求最少多少页看完所有知识点 必须说,STL够屌.. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio>

HDU 5672 String 尺取法追赶法

String Problem Description There is a string S.S only contain lower case English character.(10≤length(S)≤1,000,000)How many substrings there are that contain at least k(1≤k≤26) distinct characters? Input There are multiple test cases. The first line

hdu-5672 String(尺取法)

题目链接: String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 有一个 10\leq10≤长度\leq 1,000,000≤1,000,000 的字符串,仅由小写字母构成.求有多少个子串,包含有至少k(1 \leq k \leq 26)k(1≤k≤26)个不同的字母? 输入描述 输入包含多组数据. 第一行有一个整数T (1\leq T\leq 10)T(1≤T≤1