洛谷 复习知识点

该文章描述了一个编程问题,涉及算法设计。小明需要复习一本书,书中知识点可能重复。目标是找出最少需要复习的连续页数来掌握所有知识点。通过使用双指针和哈希映射,可以找到最优解。程序首先去重并统计知识点,然后通过移动指针计算最小页数。
摘要由CSDN通过智能技术生成

期末考试就要来了,小明打算把一本书的所有知识点都复习完,已知该书包含n页,每页包含一个知识点x,有些页的知识点有可能是重复的,小明想知道最少可以复习连续的多少页,可以把所有的知识点复习完。

第一行包含一个正整数n(1<=n<=1000000)代表该书包含多少页

第二行包含n个非负整数,代表每页包含的知识点,已知所有的知识点都在int的范围内

输出最少可以复习连续的多少页,可以把所有的知识点复习完。

输入:

5
1 8 8 8 1

 输出:

2

代码(有详细注释):

#include <bits/stdc++.h>  //万能头文件

using namespace std;

int n, l, r, ans, cnt;
set<unsigned int> s;  //将知识点去重,统计个数 
map<unsigned int, int> H;
unsigned int a[1000009];

int main () {
	
	cin >> n;  //输入n 
	
	for (int i = 1; i <= n; i++) {
		cin >> a[i];  //输入 
		s.insert(a[i]);  //推入set 
	}
	
	ans = n; //初始化,最坏情况 把所有知识点看完
	l = 1; r = 1; //初始化双指针
	cnt = 0;  //没看书之前不会任何知识点 
	
	while (1) {
		//1.l保持不动,尽可能增大r
		while (r <= n && cnt < s.size()) /*复习的知识点总数等于整本书就跳出*/ {
			//cnt == size 跳出 表示找到了一种复习方案
			//r指向的位置是将要学习的内容
			H[a[r]]++;
			if (H[a[r]] == 1) cnt++;  //"==1"表示这个知识点第一次出现
			r++;
		}
		//2.出口 没有符合题意的方案 
		if (cnt < s.size()) break;  //r > n 没有元素了
		//3.更新答案 
		ans = min (ans, r - l);  //跟区间长度比较 
		//4.向右移动l 只会移动一个单位
		H[a[l]]--;
		if (H[a[l]] == 0) cnt--;  //表示当前知识点已经复习到了
		l++;
	}
	
	cout << ans;
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值