深圳幻海软件技术有限公司 欢迎您!

北大ACM3320——Jessica's Reading Problem

2023-04-27

这一题,是简单的取尺法的应用。题目大概的意思是:一个人复习一本书,这本书的每一页都有一个知识点ai,每一页的知识点可能会与其他页的知识点相同,问你如何读最少页,将所以知识点读完。使用STL中的set来判断里面有多少个不同的知识点num,用STL中的map表示知识点与出现次数的映射。同样的设置知识点数

这一题,是简单的取尺法的应用。

题目大概的意思是:一个人复习一本书,这本书的每一页都有一个知识点ai,每一页的知识点可能会与其他页的知识点相同,问你如何读最少页,将所以知识点读完。

使用STL中的 set 来判断里面有多少个不同的知识点num, 用STL中的 map 表示知识点与出现次数的映射。

同样的设置知识点数sum,页数的起点和终点s和t。首先将知识点的数组a 加入map中,直到sum >= num,更新需要看多少页,去掉开头那一页,判断知识点是否少了,少了,则 t 再自增,继续加入,否则,再去掉开头那页。不断循环,更新需要看的最少页数。


下面是AC代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <map>
  4. #include <set>
  5. using namespace std;
  6. int n;
  7. int a[1000005];
  8. int min(int x, int y)
  9. {
  10. return x > y ? y : x;
  11. }
  12. void solve()
  13. {
  14. set<int>count;
  15. for(int i = 0; i < n; i++) //数有几个不同的知识点
  16. count.insert(a[i]);
  17. int num = count.size();
  18. map<int, int>finds; //知识点与出现次数的映射
  19. int s, t, sum;
  20. s = t = sum = 0; //起始页与末尾页,知识点数的初始化
  21. int res = n;
  22. while(1)
  23. {
  24. while(t < n && sum < num)
  25. if(finds[a[t++]]++ == 0) //出现新的知识点
  26. sum++; //增加知识点数
  27. if(sum < num) //知识点数少于总的,则可以退出循环了,到尽头了
  28. break;
  29. res = min(res, t - s); //计算页数
  30. if(--finds[a[s++]] == 0) //去掉起始页,判去掉该知识点,该知识点的次数是否为0,是,则知识点数 - 1
  31. sum--;
  32. }
  33. printf("%d\n", res);
  34. }
  35. int main()
  36. {
  37. scanf("%d", &n);
  38. for(int i = 0; i < n; i++)
  39. scanf("%d", &a[i]);
  40. solve();
  41. return 0;
  42. }