zoukankan      html  css  js  c++  java
  • nyoj133_子序列_离散化_尺取法

    子序列

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:5
     
    描述

    给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次。

    如2 8 8 8 1 1,所求子串就是2 8 8 8 1。

     
    输入
    第一行输入一个整数T(0<T<=5)表示测试数据的组数
    每组测试数据的第一行是一个整数N(1<=N<=1000000),表示给定序列的长度。
    随后的一行有N个正整数,表示给定的序列中的所有元素。
    数据保证输入的整数都不会超出32位整数的范围。
    输出
    对于每组输入,输出包含该序列中所有元素的最短子序列的长度
    样例输入
    2
    5
    1 8 8 8 1
    6
    2 8 8 8 1 1
    样例输出
    2
    5



    解题思路:刚开始看了网上的解题报告,有个类似的题,可以用stl中的集合set和键值对map来做,结果超时,实践发现每次数据一大,用STL就会超时。
    离散化
    :将a数组的备份temp[]排序,然后把不重复的值都弄到X数组中,接下来开始挨着求出a中的每一个元素在X中的位置,用index记录。
      这样每次到a[i],index[i]中记录的就是a[i]在X[]中的位置。
      尺取法:
      通过观察发现,所求序列的第一个一定是在序列中只出现1次的,不然就可以直接把这个舍去了。
      
    设置s,e分别为所求序列的起始和结束。
      e每次都++,然后当序列中元素个数==非重复元素个数len时,要用minn记录此时序列长度。然后再s++(直到X[index[s]]==1)。
      最后到e不小于n然后结束。
      
      

     代码:

    #include<cstdio>
    #include <iostream>
    #include<map>
    #include<set>
    #include<algorithm>
    #include <cstring>
    #define MAXN 1000005
    
    using namespace std;
    
    int n;
    int cou;
    int a[MAXN];//所有元素
    int X[MAXN];//不重复元素
    int temp[MAXN];//临时
    int inde[MAXN];//存储a[]中每一个元素在X中的下标
    
    int bin_search(int cou,int aa){
        int s=0,e=cou-1;
        int mid;
        while(s<=e){
            mid=(s+e)>>1;
            if(X[mid]==aa){
                return mid;
            }else{
                if(aa<X[mid]){
                    e=mid-1;
                }else{
                    s=mid+1;
                }
            }
    
        }
    }
    
    void discrete(){
        cou=1;
        sort(temp,temp+n);
        X[0]=temp[0];
        for(int i=1;i<n;i++){
            if(temp[i]!=temp[i-1]){
                X[cou++]=temp[i];
            }
        }
        for(int i=0;i<n;i++){
            inde[i]=bin_search(cou,a[i]);
        }
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--){
    
            int minn=1000005;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%d",&a[i]);
                temp[i]=a[i];
            }
            discrete();
            memset(X,0,sizeof(X));
            int len=cou;
            int s=0,e=0;
            int number=0;
            while(e<n){
                if(X[inde[e]]==0) number++;
                X[inde[e]]++;
                while(X[inde[s]]>=2){
                    X[inde[s]]--;
                    s++;
                }
                if(number==len){
                    minn=min(minn,e-s+1);
                    /*if(X[inde[s]]==1)*/ number--;
                    X[inde[s]]--;
                    s++;
                }
                e++;
            }
            printf("%d
    ",minn);
        }
        return 0;
    }
  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/TWS-YIFEI/p/5813488.html
Copyright © 2011-2022 走看看