• hdu 2158 最短区间版大家来找碴(尺取法)


    Problem Description
    给定一个序列,有N个整数,数值范围为[0,N)。
    有M个询问,每次询问给定Q个整数,可能出现重复值。
    要求找出一个最短区间,该区间要包含这Q个整数数值。
    你能找的出来吗?
     
    Input
    第一行有两个整数N,M。(N<100000, M<1000)接着一行有N个整数。再有M个询问,每个询问的第一行有一个整数Q(Q<100),第二行跟着Q个整数。当N,M同时为0时,输入结束。
     
    Output
    请输出最短区间的长度。保证有解。
     
    Sample Input
    5 2
    1 2 2 3 1
    3
    1 2 3
    3
    1 1 3
    0 0
     
    Sample Output
    3
    2
     
    题意:要求找出一个最短区间,该区间要包含这Q个整数数值。
    思路:尺取
    #include <cstdio>
    #include <map>
    #include <iostream>
    #include<cstring>
    #include<bits/stdc++.h>
    #define ll long long int
    #define M 6
    using namespace std;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
    int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    int n,m,q;
    int a[100007];        //询问数组 
    int temp[107];
    bool vis[100007]; //标记为需求数 
    int num[100007]; //需求数的数量 
    int main(){
        ios::sync_with_stdio(false);
        while(~scanf("%d%d",&n,&m)){
            if(!n&&!m) break;
            for(int i=1;i<=n;i++)
                scanf("%d",a+i);
            for(int i=1;i<=m;i++){
                memset(vis,0,sizeof(vis));
                memset(num,0,sizeof(num));
                scanf("%d",&q);
                int sum=0;
                for(int j=1;j<=q;j++){
                    scanf("%d",temp+j);
                    if(!vis[temp[j]]) vis[temp[j]]=1,sum++;
                }
                int ans=inf; int u,v,s;
                u=v=1;
                s=0;
                while(1){
                    while(v<=n&&s<sum){
                        if(vis[a[v]]&&!num[a[v]]) num[a[v]]++,s++; //如果是需求数且没出现则s++ 
                        else if(num[a[v]]) num[a[v]]++;//不然只记录下数目 
                        v++;
                    }
                    if(s<sum) break;
                    ans=min(ans,v-u);
                    if(vis[a[u]]&&num[a[u]]==1) num[a[u]]--,s--;    //与上面对应 
                    else if(num[a[u]]>1) num[a[u]]--;
                    u++;
                }
                cout<<ans<<endl;
            }
        }
    }
  • 相关阅读:
    洛谷 P2958 [USACO09OCT]木瓜的丛林Papaya Jungle
    洛谷 P1400 塔
    10-2 集合之List
    主从数据库
    【单元测试】
    Pen Editor
    appendGrid
    动画
    JavaScript框架设计 第14章 动画引擎
    >>>
  • 原文地址:https://www.cnblogs.com/wmj6/p/10386505.html
Copyright © 2020-2023  润新知