poj 3320 Jessica's Reading Problem
2016-04-09 16:09
393 查看
这道题的题意是求能够把全部知识点都覆盖的最小页数,就比如:
1 2 2 2 1
只需要读前两页就能读完所有知识点,因此答案即为2.
那么对于这道题的做法来说,需要选择hash表跟尺取法。
我们以以下数列为例:
12 13 15 17 13 12 15 12 17 15
每一次先寻找到一个能够覆盖所有知识点的区间[s,t](t<=书页总数目),然后把开头s去掉,如果此时开头s这个知识点的出现次数为0的话,就要把区间内知识点的总数-1.
接着在寻找一个能够覆盖所有知识点的区间[s+1,t'](t'<=书页总数目),然后把开头s+1去掉,如果此时开头s+1这个知识点的出现次数也为0的话,就把区间内知识点的总数-1。以此不断的推进t跟s,每一次新加页出现某知识点的话,就要把该知识点出现的次数加1.
于是,对于每一次寻找的数列为:
12 13 15 17
13 15 17 13 12
15 17 13 12
17 13 12 15
13 12 15 12 17
12 15 12 17 15
另外,输入输出记得用cin,cout会超时。#include <cstdio>
#include <map>
#include <set>
int a[1000004];
using namespace std;
int main()
{
int n;
while (~scanf("%d",&n))
{
set<int> t_set;
map<int, int> t_map;
for (int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
t_set.insert(a[i]);
}
int cnt = t_set.size();
int left = 0;
int right = 0;
int num = 0;
int res = n;
while (true)
{
while (right < n&&num < cnt)
{
if (!t_map[a[right]])
{
num++;
}
t_map[a[right]]++;
right++;
}
if (num < cnt)
break;
res = res < right - left ? res : right - left;
t_map[a[left]]--;
if (!t_map[a[left]])
num--;
left++;
}
printf("%d\n",res);
}
return 0;
}
1 2 2 2 1
只需要读前两页就能读完所有知识点,因此答案即为2.
那么对于这道题的做法来说,需要选择hash表跟尺取法。
我们以以下数列为例:
12 13 15 17 13 12 15 12 17 15
每一次先寻找到一个能够覆盖所有知识点的区间[s,t](t<=书页总数目),然后把开头s去掉,如果此时开头s这个知识点的出现次数为0的话,就要把区间内知识点的总数-1.
接着在寻找一个能够覆盖所有知识点的区间[s+1,t'](t'<=书页总数目),然后把开头s+1去掉,如果此时开头s+1这个知识点的出现次数也为0的话,就把区间内知识点的总数-1。以此不断的推进t跟s,每一次新加页出现某知识点的话,就要把该知识点出现的次数加1.
于是,对于每一次寻找的数列为:
12 13 15 17
13 15 17 13 12
15 17 13 12
17 13 12 15
13 12 15 12 17
12 15 12 17 15
另外,输入输出记得用cin,cout会超时。#include <cstdio>
#include <map>
#include <set>
int a[1000004];
using namespace std;
int main()
{
int n;
while (~scanf("%d",&n))
{
set<int> t_set;
map<int, int> t_map;
for (int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
t_set.insert(a[i]);
}
int cnt = t_set.size();
int left = 0;
int right = 0;
int num = 0;
int res = n;
while (true)
{
while (right < n&&num < cnt)
{
if (!t_map[a[right]])
{
num++;
}
t_map[a[right]]++;
right++;
}
if (num < cnt)
break;
res = res < right - left ? res : right - left;
t_map[a[left]]--;
if (!t_map[a[left]])
num--;
left++;
}
printf("%d\n",res);
}
return 0;
}
相关文章推荐
- redis源码阅读-dict
- CodeForces 616D Longest k-Good Segment
- POJ 3320 Jessica's Reading Problem
- C开源hash代码uthash的用法总结(1)
- Educational Codeforces Round 5 (D. Longest k-Good Segment)(尺取法)
- poj 3320Jessica's Reading Problem 尺取法初探(首尾指针法)
- hash表海量查找字符串(java版)
- bzoj-2082 Divine divisor
- HDU_4123 && POJ_4003 Bob’s Race (dfs / bfs + RMQ + 尺取)
- 哈希表----在VOIP用户信息存储中的应用
- poj2100尺取法
- poj 2566 Bound Found(尺取法)
- 尺取法
- poj 3061 Subsequence
- LA 2678 Subsequence(尺取法)
- LeetCode 15 3Sum(尺取法或哈希)
- 2012福建省信息学奥林匹克CCF NOIP夏令营第三天训练
- leetcode290---Word Pattern
- Pat(Advanced Level)Practice--1039(Course List for Student)
- 玛雅人的密码