解题报告 数学

1、函数 又是函数

问题描述

 话说leve最最最讨厌数学,每次考试都因为数学悲剧…….

 大头头还极其可恶的冒天下之大不韪的让同学们把那本16开500页的2012高考数学核按钮做完(为什么要叫核按钮呢?你懂得)…….

现在,leve被一道函数题难住了,为了省出更多的时间学oi,她把这道题交给了你。

给定一个函数f(x),它的定义域为1~n,值域为1~m,为了简化题目,现在将每个x对应的f(x)都告诉你。现在,你的任务就是求出一段最小的连续的区间,使得这段区间内x对应的f(x)可以取遍1~m之间的数,输出这段区间的长度。

输入文件

共两行,第一行两个数n,m。

第二行n个数 第i个数是i对应的函数值。每两个数中间有一个空格隔开,结尾无空格。

输出文件

一个数,要求的区间长度。数据保证有解。

样例输入

7 6

6 1 2 4 4 5 3

样例输出

7

数据范围

n<=1000000  m<=n

 

Liukeke 的学科试题之一·数学。

 

维护一个队列,每一次进队一个元素,如果这个元素所对应的值是第一次出现的话,给标记 +1 ,等标记 >= m 时,试图用队列长度更新 ans 

所需要注意的是,每进队一个元素都要试图出队一次,将队首能出队的都出队了,用 while 控制。

就是这样,没什么难的。

 

代码 (SueMiller

program ACRush;

 

var n,m:longint;

    a:array[0..1000010]of longint;

    v:array[0..1000010]of longint;

    i,j,k,l,r,ans:longint;

 

begin

  assign(input,'math.in');reset(input);

  assign(output,'math.out');rewrite(output);

 

  fillchar(a,sizeof(a),0);

  fillchar(v,sizeof(v),0);

  readln(n,m);

  for i:=1 to n do

    begin

      read(a[i]);

    end;

  readln;

 

  l:=1;r:=0;

  ans:=maxlongint;

  for i:=1 to n do

    begin

      if v[a[i]]=0 then inc(r);

      inc(v[a[i]]);

 

      while v[a[l]]>1 do 

        begin

          dec(v[a[l]]);

          inc(l);

        end; 

 

      if r>=m then

        if i-l+1<ans then ans:=i-l+1; 

    end;

  writeln(ans);

//  writeln(l,' ',r);

 

  close(input);close(output);

end.

 

原文地址:https://www.cnblogs.com/SueMiller/p/2223876.html