• 【t011】最小覆盖子串


    Time Limit: 1 second
    Memory Limit: 32 MB

    【问题描述】

    给定一个含有N个元素的序列A,你的任务就是求出序列A的最小覆盖子串的长度。
    本题中的一些定义:
    串S,是由零个或多个元素组成的序列,其下标从1开始计数。Si 表示串 S 中第 i 个位置的元素值,串的长度N指的是串中元素的个数。
    串中任意连续(非空)个元素组成的序列称为该串的子串。子串可以表示成S’:Si,…,Sj,1≤i≤j≤N。
    如果子串 S’ 中的不同元素值个数与原串 S 中的不同元素值个数相同,我们称子串 S’ 为原串 S 的覆盖子串,长度最小的覆盖子串称之为原串的最小覆盖子串,我们的任务就是求出最小覆盖子串的长度。
    

    【输入格式】

    输入数据的第一行为一个整数N,表示序列中有N个整数(1≤ N ≤1,000,000),序列中不同元素值的个数不超过100,000。第二行有N个整数A1,…,An。
    0≤ Ai ≤ 1,000,000,000            1≤i≤N
    

    【输出格式】

    输出一行一个整数L,表示给定序列的最小覆盖子串的长度。
    

    【输入样例1】

    5
    1 8 8 8 1
    

    【输出样例1】

    2
    

    【输入样例2】

    11
    5 1 5 3 2 6 3 8 4 2 5
    

    【输出样例2】

    8
    

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t011

    【题意】

    【题解】

    /*
        维护一个队列;
        先把第一个元素加入队列;
        对于新读入的元素;
        看看是不是和头节点相同;
        如果和头节点相同
        则把头结点去掉;
        然后头结点指向下一个值;
        然后如果该值在这个队列中出现了多次;>1
        则继续递增头结点;
        如果队列中不同的元素个数和原序列相同了就尝试更新答案;
    */


    【完整代码】

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <map>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int, int> pii;
    typedef pair<LL, LL> pll;
    
    const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
    const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
    const double pi = acos(-1.0);
    const int N = 1e6+100;
    
    int a[N],n,head,tail,tot,dl[N],now ,ans;
    map <int, int> dic1,dic2;
    
    void in()
    {
        rei(n);
        rep1(i, 1, n)
        {
            rei(a[i]);
            if (!dic1[a[i]])
            {
                dic1[a[i]] = 1;
                tot++;
            }
        }
    }
    
    void ga()
    {
        ans = N;
        head = tail = 1;
        dic2[a[1]] = 1,dl[1] = a[1];
        now = 1;
        if (now == tot)
            ans = min(ans, 1);
        rep1(i, 2, n)
        {
            dl[++tail] = a[i];
            if (!dic2[a[i]])
            {
                dic2[a[i]] = 1;
                now++;
            }
            else
                dic2[a[i]]++;
            while (dic2[dl[head]] > 1)
            {
                dic2[dl[head]]--;
                head++;
            }
            if (now == tot)
            {
                ans = min(ans, tail - head + 1);
            }
        }
    }
    
    void out()
    {
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        in();
        ga();
        out();
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
    
  • 相关阅读:
    【7.19 graphshortestpath graphallshortestpaths函数】matlab 求最短路径函数总结
    【7.18 灾情巡视路线代码】
    【7.18总结】KM算法
    【7.17总结】 匈牙利算法(二分图最大匹配)
    动态规划 多段图最短路 有向图
    matlab 单元最短路 Dijkstra算法 无向图
    hdu 3536【并查集】
    博弈随笔
    AtCoder Regular Contest 094 D Worst Case【思维题】
    CODE FESTIVAL 2017 qual B C 3 Steps(补题)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626549.html
Copyright © 2020-2023  润新知