POJ 3320 Jessica's Reading Problem

Jessica's Reading Problem
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 6001   Accepted: 1800

Descriptionios

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.app

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.ide

Inputidea

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.spa

Outputcode

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

Sample Inputip

5
1 8 8 8 1

Sample Outputci

2
題目大意:輸入一串數字,球連續數字串的最短長度,使得數字串包含數字串中的全部字符。
解題方法:用哈希表統計每一個數字出現的次數,而後求最短長度,關於這道題不少人用哈希表+二分,這樣時間複雜度爲O(n*logn),我採用的方法是用i,j兩個下標直接遍歷,時間複雜度爲O(n)。
#include <stdio.h>
#include <iostream>
using namespace std;

#define  MAX_VAL 1000050

typedef struct 
{
    int x;
    int nCount;
}Hash;

Hash HashTable[1000050];//哈希表,統計數字出現的次數
int Maxn = 0;//統計總共有多少個不一樣的數字
int ans[1000050];//ans[i]表明當出現的不一樣數字個數爲i的時候的最短長度
int num[1000050];//輸入的數字

//插入哈希表
void InsertHT(int n)
{
    int addr = n % MAX_VAL;
    while(HashTable[addr].nCount != 0 && HashTable[addr].x != n)
    {
        addr = (addr + 1) % MAX_VAL;
    }
    HashTable[addr].nCount++;
    HashTable[addr].x = n;
}

//獲得哈希表中元素的地址
int GetAddr(int n)
{
    int addr = n % MAX_VAL;
    while(HashTable[addr].nCount != 0 && HashTable[addr].x != n)
    {
        addr = (addr + 1) % MAX_VAL;
    }
    return addr;
}

int main()
{
    int n;
    scanf("%d", &n);
    if (n == 1)
    {
        printf("1\n");
        return 0;
    }
    for (int i = 0; i <= n; i++)
    {
        ans[i] = 100000000;
    }
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &num[i]);
    }
    int i = 0, j = 1;
    InsertHT(num[0]);
    while(j < n)
    {
        //若是某個數字的計數爲0,則說明這是一個新數字,因此Maxn加1
        if (HashTable[GetAddr(num[j])].nCount == 0)
        {
            Maxn++;
        }
        InsertHT(num[j]);//將數字插入到哈希表
        //i從前向後遍歷,若是某個數字的出現次數大於1,則i加1
        while(HashTable[GetAddr(num[i])].nCount > 1)
        {
            HashTable[GetAddr(num[i])].nCount--;
            i++;
        }
        //每次記錄當前不一樣數字爲Maxn的最短長度
        ans[Maxn] = min(ans[Maxn] ,j - i + 1);
        j++;//j加1,跳轉到下一個數字
    }
    printf("%d\n", ans[Maxn]);//最後打印的結果即爲全部數字都出現的最短連續子序列
    return 0;
}
相關文章
相關標籤/搜索