您的位置:首页 > 其它

[NOIP集训]10月16日

2015-10-16 18:32 155 查看
今天的文件夹:10月16日.zip

毕竟是第一天,题目比较简单,简单说下做法。

T1:对区间按左端点为第一关键字,右端点为第二关键字进行排序,然后计算可合并的区间,即前面区间的右端点不小于后面区间的左端点,这样合并后,新区间的右端点为二者右端点中的较大值。

T2:这题跪了一次。样例太有误导性,严重差评。题意是

询问在时间$[x,y]$内海浪高度第$K$小的单位时刻是那个时刻。
但由于样例太弱,错以为是

询问在时间$[x,y]$内海浪高度第$K$小的海浪高度值。
除了这个问题,别的都很简单了,抽出该区间(注意用传值的方式,不要改变原数组),进行一次“半快排”(每次递归调用时,只对包含第$K$个位置的一边进行操作,另半边不管),最后查找原数组中与构造出的这个数组的第$K$位相同的位置(即满足$a_j=a^{'}_{K}$的$j$),输出。

T3:稳定版快排,加一个关键字表示读入顺序即可。注意实数的处理要求保留4位小数,最后输出时再取整。

代码:

program find;
type
people=record
nam:ansistring;
dis:double;
num:longint;
end;
var
n,k:longint;
a:array[1..200000] of people;
i,j:longint;
x,y:double;
c:char;
now:longint;
l,r:longint;
procedure swap(var x,y:people);
var
ls:people;
begin
ls:=x;
x:=y;
y:=ls;
end;
function leq(a,b:people):boolean;
begin
if a.dis<b.dis then
exit(true);
if a.dis>b.dis then
exit(false);
if a.num<b.num then
exit(true)
else
exit(false);
end;
procedure qsort(l,r:longint);
var
i,j:longint;
p:people;
begin
i:=l;
j:=r;
p:=a[(l+r) div 2];
repeat
while leq(a[i],p) do
inc(i);
while leq(p,a[j]) do
dec(j);
if i<=j then
begin
swap(a[i],a[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then
qsort(l,j);
if i<r then
qsort(i,r);
end;
begin
assign(input,'find.in');
reset(input);
assign(output,'find.out');
rewrite(output);
readln(n,k);
for i:=1 to n do
begin
read(c);
a[i].nam:='';
while c<>' ' do
begin
a[i].nam:=a[i].nam+c;
read(c);
end;
readln(x,y);
a[i].dis:=trunc(sqrt(x*x+y*y)*10000)/10000;
a[i].num:=i;
end;
qsort(1,n);
a[n+1].dis:=a
.dis;
now:=0;
for i:=1 to k-1 do
begin
inc(now);
while (a[now].dis=a[now+1].dis)and(now<=n) do
inc(now);
if now>n then
begin
writeln('555...');
close(input);
close(output);
halt;
end;
end;
inc(now);
write(trunc(a[now].dis));
l:=now;
r:=l;
while (a[r].dis=a[r+1].dis)and(r<n) do
inc(r);
writeln(' ',r-l+1);
for i:=l to r do
writeln(a[i].nam);
close(input);
close(output);
end.


find.pas
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: