poj 3320 Jessica's Reading Problem

题意:有n页书,每页有个编号为ci的知识点,求最小看连续的页数,其中包括所有的知识点

分析:n<=1e6,只能搞O(n)的解法,无非就是枚举起点和终点,尺取法正好适合这个想法,枚举一个起点,然后往后扫描到区间内包括所有的知识点,然后每次起点都往右移动一次,直到扫描到右边界也没有答案了,就跳出

程序跑了469ms,应该是map太慢,可以hash搞一波,也过了,但是可以离散化知识点的编号,最多有1e6个,空间换时间

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e6+5;
int c[maxn];
map<int,int> v;

int main(){
    int n;
    while(~scanf("%d",&n)){
        v.clear();
        int count=0;
        for(int i=0;i<n;i++){
            scanf("%d",c+i);
            if(v[c[i]]==0){
                v[c[i]]=1;
                count++;
            }
        }
        int ans=n+1;int cnt=0,l=0,r=0;
        v.clear();
        for(;;){
            while(r<n&&cnt<count){
                if(v[c[r]]==0)cnt++;
                v[c[r++]]++;
            }
            if(cnt<count)break;
            ans=min(ans,r-l);
            if(v[c[l]]==1)cnt--;
            v[c[l++]]--;
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

hash,跑了250ms,速度提升了一半

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
const int maxn=1e6+5;
int c[maxn],v[maxn];
inline int hash(int x){
    return x%699997;
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        memset(v,0,sizeof(v));
        int count=0;
        for(int i=0;i<n;i++){
            scanf("%d",c+i);
            if(v[hash(c[i])]==0){
                v[hash(c[i])]=1;
                count++;
            }
        }
        int ans=n+1;int cnt=0,l=0,r=0;
        memset(v,0,sizeof(v));
        for(;;){
            while(r<n&&cnt<count){
                if(v[hash(c[r])]==0)cnt++;
                v[hash(c[r++])]++;
            }
            if(cnt<count)break;
            ans=min(ans,r-l);
            if(v[hash(c[l])]==1)cnt--;
            v[hash(c[l++])]--;
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2016-06-08 21:49  N维解析几何  阅读(161)  评论(0编辑  收藏  举报