zoukankan      html  css  js  c++  java
  • hdu2158 最短区间版大家来找碴

    题意:
                     最短区间版大家来找碴


    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

    Hint
    第二个查询,找到的区间是[4,5]

    思路:

          这个题目做的有点纠结,我的时间复杂度没次询问都是O(N)的,那么一次测试的时间复杂度就是O(N*M)这样是1e了,这样估计就TLE了,但是却AC了,虽然理论上测试数据是随机数据,但是感觉还是有点勉强。我的思路是先找到一个最基本的L,R然后L不停的往后挤,然后维护R来保证当前的区间的正确性,同时更新最小值(这次的代码写的有点挫-_-).


    #include<stdio.h>
    #include<string.h>
    
    #define N 110000
    
    int num[N] ,markc[N] ,markq[N];
    
    int main ()
    {
       int n ,m ,q ,a ,i;
       while(~scanf("%d %d" ,&n ,&m) && n + m)
       {
          for(i = 1 ;i <= n ;i ++)
          scanf("%d" ,&num[i]);
          while(m--)
          {
             scanf("%d" ,&q);
             memset(markc ,0 ,sizeof(markc));
             memset(markq ,0 ,sizeof(markq));
             int ss = 0;
             for(i = 1 ;i <= q ;i ++)
             {
                scanf("%d" ,&a);
                if(!markq[a]) ss ++;
                markq[a] = 1;
             }
             int L ,R ,nowsum ,Ans;
             L = 1 ,nowsum = 0 ,Ans = n;
             //找到LR
             for(i = 1 ;i <= n ;i ++)
             {
                if(markq[num[i]]) 
                {
                   if(!markc[num[i]]) nowsum ++;
                   markc[num[i]] ++;
                   if(nowsum == ss) 
                   {
                      R = i;
                      break;
                   }
                }
             }
             Ans = R - L + 1; 
             for(i = L ;i <= n ;i ++)
             {
                if(markq[num[i]]) 
                if(!(--markc[num[i]]))
                {
                   int ok = 0;
                   for(int j = R + 1 ;j <= n ;j ++)
                   {
                      if(markq[num[j]])
                      {
                         markc[num[j]] ++;
                         if(num[j] == num[i])
                         {
                            ok = 1;
                            R = j;
                            break;
                         }
                      }
                   }
                   if(!ok) break;
                }
                if(Ans > R - i) Ans = R - i;
             }
             printf("%d
    " ,Ans);
          }
       }
       return 0;
    }
          
    

  • 相关阅读:
    Vue3+Element-Plus-admin
    uniapp UI库推荐 uView官网/文档
    js 获取本月月初和月末时间操作
    el-dialog 无法弹出来
    Vue核心技术 Vue+Vue-Router+Vuex+SSR实战精讲
    sed 相关命令
    docker 启动 ubuntu
    vue 配置 history 模式
    typescript 相关
    fiddler 图片下载
  • 原文地址:https://www.cnblogs.com/csnd/p/12062793.html
Copyright © 2011-2022 走看看