洛谷:P1638 逛画展(线性复杂度优化 / 离散化,普及/提高-)

题目:

在这里插入图片描述

分析:

很明确,找一个区间,包含所有的数。

太菜了,只能想到暴力。

说说自己有多菜,暴力统计个数需要每次都遍历查看吗?你难道不会设个双指针吗?

当然啦!直接移动是不行的,需要引入一个cnt来记录双指针之间内部数字的个数。

每次都找到最小区间,然后右指针移动直到有和左指针相同的元素,然后左指针再移动确保是最小的区间。

代码:

#include<bits/stdc++.h>
using namespace std;
int m,n;
int A[1000005];
int cnt[1000005];
int main()
{
 cin>>m>>n;
 if(n==1) 
 {
  cout<<1<<' '<<1;
  return 0;
 }
 for(int i=0;i<m;i++) scanf("%d",&A[i]);
 memset(cnt,0,sizeof(cnt));
 //第一组 
 int b=0;
 int e;
 int minn_b,minn_e;
 int minn_len=1000005;
 set<int> s;
 for(e=0;e<m;e++)
 {
  s.insert(A[e]);
  cnt[A[e]]++;
  if(s.size()==n) 
  { 
   //左指针移动,确保是最小的区间。
   while(cnt[A[b]]!=1)
   {
    cnt[A[b]]--;
    b++;
    } 
    minn_len=e-b;
   minn_b=b,minn_e=e;
   break;
  }
 }
 //cout<<minn_b+1<<' '<<minn_e+1<<endl;
 //cout<<"------"<<cnt[1]<<endl;
 for(e++;e<m;e++)
 {
  cnt[A[e]]++;
  //cout<<e<<"------"<<' '<<cnt[1]<<endl;
  if(A[e]==A[b])
  {
   //cout<<"------"<<cnt[1]<<endl;
   while(cnt[A[b]]!=1)
   {
    cnt[A[b]]--;
    b++;
   }
   if(minn_len>e-b) minn_b=b,minn_e=e;
   minn_len=min(minn_len,minn_e-minn_b);
  }
 }
 cout<<minn_b+1<<' '<<minn_e+1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值