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.审题时对数据范围出现了一个偏差,对于求子序列的和,做出了一个错误的判断。
全部评论

相关推荐

能干的三文鱼刷了10...:公司可能有弄嵌入式需要会画pcb的需求,而且pcb能快速直观看出一个人某方面的实力。看看是否有面试资格。问你问题也能ai出来,pcb这东西能作假概率不高
点赞 评论 收藏
分享
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-29 17:30
找实习找着找着就要进入7月了,马上秋招也要开始了,找实习还有意义吗?
绝迹的星:有面就面, 没面上就当日薪4位数大佬免费培训, 面上了再考虑要不要实习
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务