• Justoj 2388最短区间 贪心


    2388: 最短区间

    Time Limit: 1 s      Memory Limit: 128 MB     

    Submit My Status

    Problem Description

    有M种不同颜色的气球(颜色从1至M表示),现在有一排N个位置,需要往这N个位置中填充一些气球,可填也可不填。求最短的区间长度使的这个区间中包含M种颜色的气球。如果没有则输入-1.

    Input

    第一行输入N和M,N表示位置长度,M表示气球颜色数量。(1≤M≤1000,1≤N≤106)(1≤M≤1000,1≤N≤106)。

    第二行输入N个数,第i个数ai表示第i个位置气球的颜色,0表示没填充气球。(0≤ai≤M)(0≤ai≤M)

    Output

    输出符合要求的最短区间长度,没有则输入-1。

    Sample Input

    10 6
    1 2 3 4 6 3 0 1 2 5

    Sample Output

    7

    题解:用数组p记录颜色,数组cnt记录各颜色出现次数,x代表所取区段的头部,num记录颜色种类,当遍历到头部颜色出现两次,头部往后移动直至该头部颜色只出现一次(目的就是不改变颜色种类的前提下通过移动头部缩短区间长度),每次遍历判断一下颜色种类是否达到,达到则取最短区间长度。

    #include<iostream>
    #define ll long long
    using namespace std;
    ll p[1000011],cnt[1011];
    int main()
    {
            ll n,m,x,mn,num;
            scanf("%lld %lld",&n,&m);
            x=0;mn=9999999999;num=0;
            for(int i=0;i<n;i++){
                    scanf("%d",&p[i]);
                    if(!p[i])//0
                            continue;
                    if(!cnt[p[i]])//未出现过的颜色
                            num++;
                    cnt[p[i]]++;//该颜色出现次数+1
                    while(!p[x]||cnt[p[x]]>1){//出现与头部相同的颜色或者头部为0,头部往后推1位
                            cnt[p[x]]--;
                            x++;
                    }
                    if(num==m)//
                            mn=min(mn,i-x+1);
            }
            printf("%d
    ",num==m?mn:-1);
            return 0;
    }
    


     

  • 相关阅读:
    LeetCode
    数据流中的中位数
    二叉搜索树的第k个结点
    对称的二叉树
    按之字形顺序打印二叉树
    把二叉树打印成多行
    二叉树的下一个结点
    链表中环的入口结点
    删除链表中重复的结点
    不用加减乘除做加法
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/10704476.html
Copyright © 2020-2023  润新知