其他分享
首页 > 其他分享> > 逛画展

逛画展

作者:互联网

逛画展

博览馆正在展出由世上最佳的 M 位画家所画的图画。

wangjy 想到博览馆去看这几位大师的作品。

可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,a 和 b,代表他要看展览中的第 a 幅至第 b 幅画(包含 a 和 b)之间的所有图画,而门票的价钱就是一张图画一元。

为了看到更多名师的画,wangjy 希望入场后可以看到所有名师的图画(至少各一张)。

可是他又想节省金钱。。。

作为 wangjy 的朋友,他请你写一个程序决定他购买门票时的 a 值和 b 值。

输入格式
第一行包含两个整数 N 和 M,表示图画总数和画家数量。

第二行包含 N 个整数,它们都介于 1 和 M 之间,代表画作作者的编号。

输出格式
输出两个整数 a 和 b。

数据保证有解,如果存在多个解,则输出 a 最小的那个解。

数据范围
1≤N≤106,
1≤M≤2000
输入样例:
12 5
2 5 3 1 3 2 4 1 1 5 4 3
输出样例:
2 7
思路分析:
滑动窗口算法
基本可以用来解决一些查找满足一定条件的连续区间的性质(长度等)的问题。由于区间连续,因此当区间发生变化时,可以通过旧有的计算结果对搜索空间进行剪枝,这样便减少了重复计算,降低了时间复杂度。往往类似于“ 请找到满足 xx 的最 x 的区间(子串、子数组)的 xx ”这类问题都可以使用该方法进行解决。
需要注意的是,滑动窗口算法更多的是一种思想,而非某种数据结构的使用。
时间复杂度为O(n)

#include<iostream>
using namespace std;
int n, m;
int h, k;
const int N = 123496189;
int left1, right1, q[N], cnt[N];//cnt数组标记当前画家的画是否已经选择
int main() {
	cin >> n >> m;
	h = 1;
	int ans = 1e9;
	for (int i = 1; i <= n; i++) {
		int x;
		cin >> x;
		if (cnt[x] == 0)
			k++;
		cnt[x]++;
		q[i] = x;
		while (h < i && k == m) {//滑动窗口的大小为m
			if (ans > i - h + 1) {
				ans = i - h + 1;
				left1 = h;
				right1 = i;
			}
			cnt[q[h]]--;
			if (cnt[q[h]] == 0)
				k--;
			h++;
		}
	}
	cout << left1 << " " << right1 << endl;
	return 0;
}

标签:cnt,图画,wangjy,画展,int,++,ans
来源: https://blog.csdn.net/dsfgsfghdhfjgk/article/details/116399772