poj 3320 Jessica's Reading Problem

来源:互联网 发布:日本杏林大学知乎 编辑:程序博客网 时间:2024/05/22 00:40
Jessica's Reading Problem
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6463 Accepted: 1985

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.

Jessica是个非常可爱的女孩子被很多男孩子追。最近她遇到了一个麻烦,期末考试又要来了啦,不过一点都没学咋整啊。。如果她不想挂树上,那么久不得不学会那一厚练习册里面的所有知识点。这本练习册的作者跟其他作者一样蛋疼,里面经常有很多重复知识点。Jessica想如果她可以把所有的知识点看那么一遍,这次就应该能侥幸过关。他决定阅读连续的几页,然后里面能够包含所有的知识点。当然,这个连续的几页越薄越好。

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.

一个非常勤劳的男孩已经帮Jessica标记好了每一页对应的知识点,然后你需要做的事情就是,给你了这个男孩做好的索引,之后你去找到最少的连续的几页中能够包含所有知识点。每个知识点都有一个ID标记,是一个正整数。

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.

第一行是有多少页P (1 ≤ P ≤ 1000000),然后第二行是每一页对应的知识点的ID,你可以认为知识点的ID不超过Int

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

51 8 8 8 1

Sample Output

2

Source

POJ Monthly--2007.08.05, Jerry

做题甚少,这种题第一次做。。。根据学习,一般思路是快排加哈希,然后用尺取法,尺取法就是创造一个区间,左边一个指针,右边一个指针,如果右边指针指向的内容第一次出现,则右移,如果是第二次出现,并且内容与左边的指针相同,则左边的指针右移,不然就说明从左到右的区间内有重负内容,则取此长度与当前最小长度比较取最小。
然后还有各种deque的方法,不太懂,还有用堆的,那方面没研究。。。
最后采用的是二分加快排,因为方法比较意外。。。主要是尺取法本身不同。。。首先对于快排后将数据整理成每个idea只出现一次的升序序列,然后在这个序列里面二分查找,后记录的是每一次idea出现所处在的最右面的位置,这究竟是怎么想的。。。。然后判断最右面的指针和左边的指针内容如果不同,则继续记录,如果相同,则从左边扫描到右边,然后将左边的指针移动到,标记的最右面位置最小的那一个,这样就保证了不会丢失idea。。。。。。
还是看程序吧。。。基本参照那个人的方法写的。。。所以这次比较水。。。

#include <iostream>#include <stdio.h>#include <string.h>#define LEN 1000001void q_sort(int p, int r);int partition_q(int p, int r);int findnext(int i, int left, int num);int Binsearch(int x, int l, int r);int page[LEN], s[LEN], index[LEN];int main(){    int p, i, j;    int num;    int left;    int minlen;    int sum;    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    while(scanf("%d", &p) != EOF){        for (i = 0;i < p;++ i){            scanf("%d", &page[i]);            s[i] = page[i];        }        q_sort(0, p - 1);        num = 1;        j = 1;        for (i = 1;i < p;++ i){            if (s[i] != s[i-1]){                num ++;                s[j] = s[i];                j++;            }        }//        for (i = 0;i < p;++ i){//            printf("%d ", s[i]);//        }//        printf(" num = %d", num);        for (i = 0;i < LEN;++ i){            index[i] = -1;        }        minlen = LEN;        left = 0;        sum = 0;        for (i = 0;i < p;++ i){            j = Binsearch(page[i], 0, num - 1);            if (index[j] == -1){                sum ++;            }else if(page[i] == page[left]){                left = findnext(i, left, num);            }            index[j] = i;            if (sum == num){                    if ((i - left + 1) < minlen)                        minlen = i - left + 1;            }        }        printf("%d\n", minlen);    }    return 0;}void q_sort(int p, int r){    int q;    if (p < r){        q = partition_q(p, r);        q_sort(p, q-1);        q_sort(q+1, r);    }}int partition_q(int p, int r){    int i = p - 1, j;    int temp;    for (j = p;j < r;++ j){        if (s[j] <= s[r]){            ++i;            temp = s[i]; s[i] = s[j]; s[j] = temp;        }    }    temp = s[i + 1]; s[i + 1] = s[r]; s[r] = temp;    return i + 1;}int Binsearch(int x, int l, int r){    int mid;    if (s[l] == x)        return l;    if (s[r] == x)        return r;    while(l <= r){        mid = l + ((r - l) >> 1);        if (s[mid] == x){            return mid;        }else if (s[mid] > x){            r = mid - 1;        }else{            l = mid + 1;        }    }    return -1;}int findnext(int i, int left, int num){    int j, k;    int rs = i;    for (j = left + 1;j < i;++ j){        k = Binsearch(page[j], 0, num-1);        if (index[k] < rs){            rs = index[k];        }    }    return rs;}


0 0