CodeForces - 224B-思維題

B - Array
You’ve got an array a, consisting of n integers: a1, a2, …, an. Your task is to find a minimal by inclusion segment [l, r] (1 ≤ l ≤ r ≤ n) such, that among numbers al,  al + 1,  …,  ar there are exactly k distinct numbers.
Segment [l, r] (1 ≤ l ≤ r ≤ n; l, r are integers) of length m = r - l + 1, satisfying the given property, is called minimal by inclusion, if there is no segment [x, y] satisfying the property and less then m in length, such that 1 ≤ l ≤ x ≤ y ≤ r ≤ n. Note that the segment [l, r] doesn’t have to be minimal in length among all segments, satisfying the given property.
Input
The first line contains two space-separated integers: n and k (1 ≤ n, k ≤ 105). The second line contains n space-separated integers a1, a2, …, an — elements of the array a (1 ≤ ai ≤ 105).
Output
Print a space-separated pair of integers l and r (1 ≤ l ≤ r ≤ n) such, that the segment [l, r] is the answer to the problem. If the sought segment does not exist, print “-1 -1” without the quotes. If there are multiple correct answers, print any of them.
Examples
Input
4 2
1 2 2 3
Output
1 2
Input
8 3
1 1 2 2 3 3 4 5
Output
2 5
Input
7 4
4 7 7 4 7 4 7
Output
-1 -1
Note
In the first sample among numbers a1 and a2 there are exactly two distinct numbers.
In the second sample segment [2, 5] is a minimal by inclusion segment with three distinct numbers, but it is not minimal in length among such segments.
In the third sample there is no segment with four distinct numbers.
Sponsor

題目大意:
給出一行n個數,要求在這n個數中找出正好含有m個不同的數的子序列。
要求:不需要輸出最短的,但是所求字符串必須在當前選擇下是最短的,沒有冗餘。輸出任意一種結果。

做題時:

  1. 這道題主要還是死在英語上,開始我以爲是求含有m個不同的數的子序列字符串,wa了,
  2. 後來以爲是求字符串和最小且含有m個不同的數的子序列,因爲clear()寫循環裏面還寫了兩個超時了,然後優化了一下,過了20組,還是wa了。
  3. 再後來發現數據很大,範圍超了,所以不可能是求和最小,於是就是求要求在這n個數中找出正好含有m個不同的數的子序列。

思路

這道題可以直接從第一個開始找,找到滿足m個不同位置的子序列最末端,也就是找到r的位置,然後再從第m往前找l的位置即可。

#include <bits/stdc++.h>
#define pb(a) push_back(a)
#define pf push_front
#define beg begin
#define e end
#define rb rbegin0
#define re rend
#define nd cout<<endl
#define all(s) s.begin(),s.end()
#define pi acos(-1.0)
#define MaxN  0x3f3f3f3f
#define MinN  0xc0c0c0c0
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N=2e5+15;
int n,m,l,r,sum,f;
int a[N],b[N];
int main()
{
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    int p=2;
    for(int i=1; i<=n; i++)
    {
        if(b[a[i]])
            continue;
        b[a[i]]=1;
        sum++;
        if(sum==m)
        {
            r=i;
            f=1;
            break;
        }
    }
    memset(b,0,sizeof(b));
    sum=0;
    for(int i=r; i>=1; i--)
    {
        if(b[a[i]])
            continue;
        b[a[i]]=1;
        sum++;
        if(sum==m)
        {
            l=i;
            break;
        }
    }
    if(f)
        cout<<l<<" "<<r<<endl;
    else
        cout<<-1<<" "<<-1<<endl;
    return 0;
}
  1. 小結一下,關於做題,還是實行

    1. 審題,題意要反覆斟酌,推敲,最後確定。
    2. 寫代碼前做一個僞代碼,或者腦海中有一個整體的思路,如果是模擬很複雜,那麼就需要寫在紙上,將各個條件分析清楚,以及條件之間的關係。
    3. 寫完代碼,需要再次花一兩分種做一個整體檢查。
      檢查內容:
      1. 數組大小(空間是否小,否則是否大)
      2. 時間複雜度
      3. 清零(空)
  2. 對於這道題目,犯的小錯誤:

    1. 超時
      1. 原因:map的clear() 在for裏面 使用了兩次,不必要的浪費時間複雜度。 當時應該檢查一次,考慮清楚要不要去掉clear(),因爲使用會造成時間複雜度過大,但後來想顯然不用。
      2.審題時對數據範圍出現了一個偏差,對於求子序列的和,做出了一個錯誤的判斷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章