北大ACM3320——Jessica's Reading Problem

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

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

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

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

下面是AC代码:

#include <iostream>
#include <cstdio>
#include <map>
#include <set>
using namespace std;

int n;
int a[1000005];

int min(int x, int y)
{
	return x > y ? y : x;
}

void solve()
{
	set<int>count;
	for(int i = 0; i < n; i++)             //数有几个不同的知识点
		count.insert(a[i]);
	int num = count.size();
	map<int, int>finds;                    //知识点与出现次数的映射
	int s, t, sum;
	s = t = sum = 0;                       //起始页与末尾页,知识点数的初始化
	int res = n;
	while(1)
	{
		while(t < n && sum < num)
			if(finds[a[t++]]++ == 0)        //出现新的知识点
				sum++;                     //增加知识点数
		if(sum < num)                      //知识点数少于总的,则可以退出循环了,到尽头了
			break;
		res = min(res, t - s);             //计算页数
		if(--finds[a[s++]] == 0)           //去掉起始页,判去掉该知识点,该知识点的次数是否为0,是,则知识点数 - 1
			sum--;
	}
	printf("%d\n", res);
}

int main()
{
	scanf("%d", &n);
	for(int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	solve();
	return 0;
}

北大ACM3320——Jessica's Reading Problem

时间: 2024-08-10 16:58:04

北大ACM3320——Jessica's Reading Problem的相关文章

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

poj3320 Jessica&#39;s Reading Problem

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 au

poj 3320 Jessica&#39;s Reading Problem

题意:有n页书,每页有个编号为ci的知识点,求最小看连续的页数,其中包括所有的知识点 分析:n<=1e6,只能搞O(n)的解法,无非就是枚举起点和终点,尺取法正好适合这个想法,枚举一个起点,然后往后扫描到区间内包括所有的知识点,然后每次起点都往右移动一次,直到扫描到右边界也没有答案了,就跳出 程序跑了469ms,应该是map太慢,可以hash搞一波,也过了,但是可以离散化知识点的编号,最多有1e6个,空间换时间 #include<iostream> #include<cstdio&

poj 3320 Jessica&#39;s Reading Problem (尺取法)

Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8787   Accepted: 2824 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 littl

尺取法 POJ 3320 Jessica&#39;s Reading Problem

题目传送门 1 /* 2 尺取法:先求出不同知识点的总个数tot,然后以获得知识点的个数作为界限, 更新最小值 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <cstring> 7 #include <algorithm> 8 #include <set> 9 #include <map> 10 using namespace std; 11 12 const int M

poj3061 Subsequence&amp;&amp;poj3320 Jessica&#39;s Reading Problem(尺取法)

这两道题都是用的尺取法.尺取法是<挑战程序设计竞赛>里讲的一种常用技巧. 就是O(n)的扫一遍数组,扫完了答案也就出来了,这过程中要求问题具有这样的性质:头指针向前走(s++)以后,尾指针(t)要么不动要么也往前走.满足这种特点的就可以考虑尺取法. poj3061 比较简单,也可以用二分做,时间复杂度O(n*logn).用尺取法可以O(n)解决. #include<iostream> #include<cstdio> #include<cstdlib> #i

Jessica&#39;s Reading Problem

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 au

POJ3320 Jessica&#39;s Reading Problem(尺取+map+set)

POJ3320 Jessica's Reading Problem set用来统计所有不重复的知识点的数,map用来维护区间[s,t]上每个知识点出现的次数,此题很好的体现了map的灵活应用 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <vector> #include &

POJ 3320 Jessica&#39;s Reading Problem 尺取法/map

Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7467   Accepted: 2369 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 littl