2071 - 双指针-练习-逛画展

c++刷题 超能力编程

在这里插入图片描述
在这里插入图片描述
首先注意到,必须看到所有的画师的画才行,所以可以考虑维护一个区间内,每个画师有多少画,可以用一个数组来维护

第一个循环中,把区间右端点不断右移,并维护该画的画师出现次数,出现新的画师把计数器加一,直到看到所有画师的画,然后循环判断左端点的画师是否出现一次以上,

这时候应用贪心思想,只要出现过一次以上,那么左端点就一定可以弹出,因为这个点的存在只会让区间更长,而不会让区间包含画师更多,我们只要保证这个区间有每个画师的画就行了,

这时用两个变量来记录当前区间左右端点作为初始答案

然后第二次循环,继续循环剩下的画,

每次将右端点+1,维护画的画师出现次数,并不断弹出没必要存在的左端点,因为在第二个循环里任何时刻的区间都保证满足能看到所有画师的画,所以应该在循环里面判断当前区间是否比已知答案的区间更短,如果更短,更新答案

我的代码区间是从零计的,所以输出时+1

虽然循环嵌套,但是因为每个点都只会最多出入一次区间,所以复杂度O(n),只是常数略大.

#include<stdio.h>
int m[2001],num;
int n[1000000];
int main()
{
    int R=-1,L=0,N,M,t,i=0,ansL,ansR;
    scanf("%d%d",&N,&M);
    for(i=0;i<N;i++)
    scanf("%d",n+i);
    i=0;
    while(num!=M)
    {
        if(m[n[i]]==0)num++;
        m[n[i]]++;
        R++;
        i++;
    }
    while(m[n[L]]>1)
        m[n[L++]]--;
    ansL=L;ansR=R;
    while(i<N)
    {
        m[n[i]]++;
        R++;
        i++;
        while(m[n[L]]>1)
            m[n[L++]]--;
        if(ansR-ansL>R-L)
        {
            ansR=R;
            ansL=L;
        }
    }
    printf("%d %d",ansL+1,ansR+1);
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值