poj3320尺取法

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题意:找最少的连续页数使得覆盖全书的所有知识点题解:尺取法,也叫做two point 很形象就是两段不断改变来找到最值。时间复杂度减低了很多

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007

using namespace std;

const int N=1000000+5,maxn=100+5,inf=0x3f3f3f3f;

int p,a[N];
set<int>ss;
map<int,int>m;

int main()
{
   /* ios::sync_with_stdio(false);
    cin.tie(0);*/
    scanf("%d",&p);
    for(int i=0;i<p;i++)
    {
        scanf("%d",&a[i]);
        ss.insert(a[i]);
    }
    int n=ss.size();
    int num=0,st=0,en=0,ans=p;
    for(;;)
    {
        while(en<p&&num<n){
            if(m[a[en++]]++==0)num++;
        }
        if(num<n)break;
        ans=min(ans,en-st);
        if(--m[a[st++]]==0)num--;
    }
    printf("%d\n",ans);
    return 0;
}

还有就是不知道为啥用cin和cout居然TLE了,而且我还加了

ios::sync_with_stdio(false);
cin.tie(0);

代码也放上来!!

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007

using namespace std;

const int N=1000000+5,maxn=100+5,inf=0x3f3f3f3f;

int p,a[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>p;
    set<int>ss;
    for(int i=0;i<p;i++)
    {
        cin>>a[i];
        ss.insert(a[i]);
    }
    int n=ss.size();
    map<int,int>m;
    int num=0,st=0,en=0,ans=p;
    for(;;)
    {
        while(en<p&&num<n){
            if(m[a[en++]]++==0)num++;
        }
        if(num<n)break;
        ans=min(ans,en-st);
        if(--m[a[st++]]==0)num--;
    }
    cout<<ans<<endl;
    return 0;
}

时间: 2024-11-09 05:48:59

poj3320尺取法的相关文章

POJ3320 尺取法的正确使用法

一.前言及题意: 最近一直在找题训练,想要更加系统的补补思维,补补漏洞什么的,以避免被个类似于脑筋急转弯的题目干倒,于是在四处找书,找了红书.蓝书,似乎都有些不尽如人意.这两天看到了日本人的白书,重新读了一遍,其中若干章节写的非常务实也实践起来相当实用,于是这就是白书上面一道推荐的题目,用于训练尺取法的例题.考虑到最近老是读错题,所以就慢慢习惯于首先把个题目翻译成中文之后在进行解读: 杰西卡是个非常可爱的女孩子,因而有若干男孩子追她,最近他的考试要到了,她需要花相当多部分的时间在这件事情上面,吐

poj3320 (尺取法)

n个数,求最小区间覆盖着n个数中所有的不相同的数字. 解题思路: AC代码: import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Scanner; import java.util.Set; public class Main{ /** * @param args */ static int n; static Set<Integer> set = new Hash

poj3061 Subsequence&amp;&amp;poj3320 Jessica&#39;s Reading Problem(尺取法)

这两道题都是用的尺取法.尺取法是<挑战程序设计竞赛>里讲的一种常用技巧. 就是O(n)的扫一遍数组,扫完了答案也就出来了,这过程中要求问题具有这样的性质:头指针向前走(s++)以后,尾指针(t)要么不动要么也往前走.满足这种特点的就可以考虑尺取法. poj3061 比较简单,也可以用二分做,时间复杂度O(n*logn).用尺取法可以O(n)解决. #include<iostream> #include<cstdio> #include<cstdlib> #i

尺取法 poj3061 poj3320

尺取法就是反复推进区间的开头和结尾,来求满足条件的最下区间. poj3061 http://poj.org/problem?id=3061 给定一个都是正整数的序列,要我们求总和不小于S的连续子序列的长度的最小值 如果序列   是总和最迟大于S的连续子序列 那么  所以只有加上, 从开始的连续子序列才有可能大于S 所以从开始的总和最初大于S的连续子序列是则一定有 1 #include <stdio.h> 2 #include <string.h> 3 #include <st

poj3320(Jessica&#39;s Reading Problem)尺取法

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 au

【尺取法】POJ3061 &amp; POJ3320

POJ3061-Subsequence [题目大意] 给定长度微n的数列整数及整数s.求出总和不小于s的连续子序列的长度的最小值.如果节不存在,则输出0. [思路] 尺取法五分钟裸裸裸~刷水刷出了罪恶感:( 基本做法:设置l和r代表当前区间[l,r],若S(l,r)<s,则 r++.若S(l,r)≥s,则 l++,直至S(l,r)<s.如果当前S(l,r)<s且r=n则退出.输出最小区间长度[l,r]即可. 1 #include<iostream> 2 #include<

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

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

尺取法 TwoPoint

就是两个指针表示区间[l,r]的开始与结束然后根据题目来将端点移动,是一种十分有效的做法.适合连续区间的问题 3320 这道意思是一本书有n页,每一页上有一个知识点标号a[i]可能重复,要求选择一个最小的区间使得能够覆盖所有知识点 分析:[l,r]区间推进,统计区间中能够覆盖的知识点数,对于每一个l,r都是满足可以覆盖所有知识点的最小r,处理好区间知识点数的统计就好了 1 #include <iostream> 2 #include <cstdio> 3 #include <

【尺取法】【转】

尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案.之所以需要掌握这个技巧,是因为尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的 使用尺取法时应清楚以下四点: 1.  什么情况下能使用尺取法?  2.何时推进区间的端点? 3.如何推进区间的端点? 3.何时结束区间的枚举? 尺取法通常适用于选取区间有一定规律,或者说所选取的区间有一定的变化趋势的情况,通俗地说,在对所选取区间进行