洛谷P1638逛畫展

名称无法显示發表於2024-10-14

逛畫展

題目連結

題目描述

博覽館正在展出由世上最佳的 \(m\) 位畫家所畫的圖畫。

遊客在購買門票時必須說明兩個數字,\(a\)\(b\),代表他要看展覽中的第 \(a\) 幅至第 \(b\) 幅畫(包含 \(a,b\))之間的所有圖畫,而門票的價錢就是一張圖畫一元。

Sept 希望入場後可以看到所有名師的圖畫。當然,他想最小化購買門票的價格。

請求出他購買門票時應選擇的 \(a,b\),資料保證一定有解。

若存在多組解,輸出 \(a\) 最小的那組

輸入格式

第一行兩個整數 \(n,m\),分別表示博覽館內的圖畫總數及這些圖畫是由多少位名師的畫所繪畫的。

第二行包含 \(n\) 個整數 \(a_i\),代表畫第 \(i\) 幅畫的名師的編號。

輸出格式

一行兩個整數 \(a,b\)

樣例 #1

樣例輸入 #1

12 5
2 5 3 1 3 2 4 1 1 5 4 3

樣例輸出 #1

2 7

提示

資料規模與約定

  • 對於 \(30\%\) 的資料,有 \(n\le200\)\(m\le20\)
  • 對於 \(60\%\) 的資料,有 \(n\le10^5\)\(m\le10^3\)
  • 對於 \(100\%\) 的資料,有 \(1\leq n\le10^6\)\(1 \leq a_i \leq m\le2\times10^3\)

雙指標解法

#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int a[N],cnt[2005];
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i];

	int num = 1, len = 1e9;
	int l = 1, r = 1;
	cnt[a[1]] = 1;
	for (int i = 1, j = 1; j <= n;) {
		if (num < m) {
			j++;
			cnt[a[j]]++;
			if (cnt[a[j]] == 1) num++;
		}
		if (num == m) {
			if (len > j - i + 1) {
				len = j - i + 1;
				l = i; r = j;
			}
			cnt[a[i]]--;
			if (cnt[a[i]] == 0) num--;
			i++;
		}
	}
	cout << l << " " << r << endl;
	return 0;
}

二分答案解法