題目來源:洛谷
題目描述
博覽館正在展出由世上最佳的 M 位畫家所畫的圖畫。
wangjy想到博覽館去看這幾位大師的作品。
可是,那裏的博覽館有一個很奇怪的規定,就是在購買門票時必須說明兩個數字,
a和b,代表他要看展覽中的第 a 幅至第 b 幅畫(包含 a 和 b)之間的所有圖畫,而門票
的價錢就是一張圖畫一元。
爲了看到更多名師的畫,wangjy希望入場後可以看到所有名師的圖畫(至少各一張)。
可是他又想節省金錢。。。
作爲wangjy的朋友,他請你寫一個程序決定他購買門票時的 a 值和 b 值。
輸入格式
第一行是 N 和 M,分別代表博覽館內的圖畫總數及這些圖畫是由多少位名師的畫
所繪畫的。
其後的一行包含 N 個數字,它們都介於 1 和 M 之間,代表該位名師的編號。
輸出格式
a和 b(a<=b) 由一個空格符所隔開。
保證有解,如果多解,輸出a最小的。
輸入輸出樣例
輸入 #1
12 5
2 5 3 1 3 2 4 1 1 5 4 3
輸出 #1
2 7
數據範圍
約定 30%的數據N<=200 , M<=20
60%的數據N<=10000 , M<=1000
100%的數據N<=1000000 , M<=2000
思路:
deque
我發現用deque來做思路好清晰,拿樣例來說吧
vis[i]:i在隊列中出現過幾次
cnt:隊列裏有幾位名畫家
樣例:
2 5 3 1 3 2 4 1 1 5 4 3
-2入隊,vis[2]=1,cnt=1
q:2
-5入隊,vis[5]=1,cnt=2
q:2 5
-3入隊,vis[3]=1,cnt=3
q:2 5 3
-1入隊,vis[1]=1,cnt=4
q:2 5 3 1
-3入隊,vis[3]=2,cnt=4
q:2 5 3 1 3
-2入隊,vis[2]=2,cnt=4
q:2 5 3 1 3 2
此時隊頭已經有1個2了,所以把隊頭彈出,vis[2]=1,cnt=4
q:5 3 1 3 2
-4入隊,vis[4]=1,cnt=5
q:5 3 1 3 2 4
此時cnt=m,隊列裏包括了所有的名畫家,可以記錄答案
ansl=2 ansr=7(怎麼記錄?隊列類型用結構體就行了)
-1入隊,vis[1]=2,cnt=5
此時cnt=m,可是不能更新答案,因爲現在買票28還不如剛纔的27,所以加個判斷
q:5 3 1 3 2 4 1
-1入隊,vis[1]=3,cnt=5
q:5 3 1 3 2 4 1 1
-5入隊,vis[5]=2,cnt=5
q:5 3 1 3 2 4 1 1 5
我們發現隊頭有個5,可以彈出
q:3 1 3 2 4 1 1 5
此時隊頭的3也可以彈出,因爲隊列裏面有2個3,vis[3]=1,cnt=5
q:1 3 2 4 1 1 5
隊頭的1也可以彈出,因爲隊列裏有3個1,
vis[1]=2,cnt=5
q:3 2 4 1 1 5
此時還不能更新答案,因爲510的長度還沒有小於27的長度,題目意思是如果多解,輸出a最小的
-4入隊,vis[4]=2,cnt=5
q:3 2 4 1 1 5 4
-3入隊,vis[3]=2,cnt=5
q:3 2 4 1 1 5 4 3
彈出隊頭的3,vis[3]=1,cnt=5
q:2 4 1 1 5 4 3
詳情見代碼:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000010],vis[2010],ansl=0,ansr=9999999;
struct node{
int num;
int id;
}e;
deque <node> q;
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
int cnt=0;
for (int i=1;i<=n;i++)
{
e.num=a[i]; e.id=i;
q.push_back(e);
if (vis[a[i]]==0) cnt++;
vis[a[i]]++;
while (q.size()!=1&&q.front().num==q.back().num) //隊尾與隊頭相同,彈出隊頭
{
vis[q.front().num]--;
if (vis[q.front().num]==0) cnt--;
q.pop_front();
}
while (vis[q.front().num]>1) //隊頭元素值在隊裏的數量超過1,可以彈出
{
vis[q.front().num]--;
if (vis[q.front().num]==0) cnt--;
q.pop_front();
}
if (cnt==m)
{
if (q.back().id-q.front().id<ansr-ansl)
ansl=q.front().id,ansr=q.back().id;
}
}
printf("%d %d\n",ansl,ansr);
return 0;
}