zoukankan      html  css  js  c++  java
  • POJ 3320 Jessica‘s Reading Problem(哈希、尺取法)

    http://poj.org/problem?id=3320

    题意:
    给出一串数字,要求包含所有数字的最短长度。

    思路:

    哈希一直不是很会用,这道题也是参考了别人的代码,想了很久。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string>
     4 #include<cstring>
     5 using namespace std;
     6 
     7 const int PRIME = 99999;
     8 
     9 int n;
    10 int len;
    11 
    12 //开散列法,也就是用链表来存储,所以下面的len是从PRIME开始的,因为前面的都是头结点。
    13 
    14 struct node       //key是数值大小,num是该key出现的次数,因为是链表存储,所以next指向下一个结点
    15 {
    16     int key;
    17     int num;
    18     int next;
    19 }p[1000005];
    20 
    21 int a[1000005];
    22 
    23 int _hash(int num)
    24 {
    25     int k = num%PRIME;     //取余
    26     while (p[k].next != -1)    //该数值已经出现过了
    27     {
    28         if (num > p[p[k].next].key)  break;      //按递减的方式排列
    29         else if (num == p[p[k].next].key)  return p[k].next;   //如果已经出现过了,直接返回
    30         k = p[k].next;
    31     }
    32     //没有出现过,添加新的结点
    33     p[len].key = num;
    34     p[len].num = 0;
    35     p[len].next = p[k].next;
    36     p[k].next = len;
    37     len++;
    38     return len - 1;
    39 }
    40 
    41 int main()
    42 {
    43     //freopen("D:\txt.txt", "r", stdin);
    44     while (~scanf("%d", &n) && n)
    45     {
    46         for (int i = 0; i < PRIME; i++)
    47             p[i].next = -1;
    48         len = PRIME;
    49         int left = 0;
    50         int ans;
    51         for (int i = 0; i < n; i++)
    52         {
    53             scanf("%d", &a[i]);
    54             int temp = _hash(a[i]);
    55             p[temp].num++;
    56             if (p[temp].num == 1)   //说明第一次出现,所以肯定要包括进去,此时ans肯定等于i-left+1
    57             {
    58                 ans = i - left + 1;
    59                 continue;
    60             }
    61             //如果之前已经出现过
    62             temp = _hash(a[left]);
    63             //如果left指向的数值后面还有出现,那么可以右移一位
    64             while (left<n - 1 && p[temp].num>1)
    65             {
    66                 p[temp].num--;
    67                 left++;
    68                 temp = _hash(a[left]);
    69             }
    70             if (ans > i - left + 1)      ans = i - left + 1;
    71         }
    72         printf("%d
    ", ans);
    73     }
    74     return 0;
    75 }

    接下来再附上尺取法的做法,主要思路和上面是差不多的。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string>
     4 #include<cstring>
     5 #include<set>
     6 #include<map>
     7 using namespace std;
     8 
     9 const int maxn = 1000000 + 5;
    10 
    11 int n;
    12 int x[maxn];
    13 set<int> p;
    14 map<int, int> q;
    15 
    16 int main()
    17 {
    18     //freopen("D:\txt.txt", "r", stdin);
    19     while (~scanf("%d", &n))
    20     {
    21         p.clear();
    22         q.clear();
    23         for (int i = 1; i <= n; i++)
    24         {
    25             scanf("%d", &x[i]);
    26         }
    27 
    28         for (int i = 1; i <= n; i++)
    29             p.insert(x[i]);
    30 
    31         int ans = n;
    32         int total = p.size();    //不重复的数
    33         int sum = 0;
    34         int left = 1, right = 1;
    35         while (left<=n && right <= n)
    36         {
    37             if (q[x[right]] == 0)  sum++; //这个数没有出现过
    38             q[x[right]]++;
    39             
    40             while (q[x[left]] > 1)
    41             {
    42                 q[x[left]]--;
    43                 left++;
    44             }
    45             if (sum == total)
    46             {
    47                 ans = min(ans, right - left + 1);
    48                 if (q[x[left]] == 1)  sum--;
    49                 q[x[left]]--;
    50                 left++;
    51             }
    52             right++;
    53         }
    54         printf("%d
    ", ans);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    将WinServers2019打造成家用系统
    WindowsServers2019上手体验
    【代码模板】不存在的NOIP2017
    NOIP2018初赛翻车总结
    【初赛】各种排序算法总结
    【Luogu1996】约瑟夫问题(模拟,解法汇总)
    【初赛】NOIP2018程序模板
    MongoDB
    非关系型数据库----MongoDB
    用Python来操作redis 以及在Django中使用redis
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6583030.html
Copyright © 2011-2022 走看看