解题报告 数学
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.