【NOIP2016提高A组模拟9.15】Osu

时间:2022-12-16 23:57:38

题目

【NOIP2016提高A组模拟9.15】Osu
Input
【NOIP2016提高A组模拟9.15】Osu

Sample Input

4 2
1 2 2
2 0 2
3 0 0
4 2 0
Output
【NOIP2016提高A组模拟9.15】Osu
Sample Output

1 2 1
样例解释:
圆圈只在出现的时刻有效。即:时刻t_i时鼠标位置恰好在(x_i,y_i)才能得分。
Kaguya所做的工作就是在这些时刻间移动鼠标。
对于样例:选择点击第2、4个圆圈。
时间[0,2]内,鼠标从(0,0)移动到(0,2),速度为1,并在时刻2得分。
时间[2,4]内,鼠标从(0,2)移动到(2,0),速度为sqrt(2),并在时刻4得分。
因此答案为sqrt(2), a=1 b=2 c=1

Data Constraint
【NOIP2016提高A组模拟9.15】Osu

比赛时の想法

60%的dp还是很明显的,直接上了~

正解

在60分的基础上我们发现一共有 20002 种可能的答案(两个点之间要到达所需要的速度),所以我们把所有可能的情况都预处理出来,排一下序,然后二分一下答案就好了

贴代码

日常不想删注释233

var
cc:array[0..2005,0..2005,1..3]of longint;
a:array[0..2005,1..3]of longint;
fe:array[0..2005,0..2005]of double;
ju:array[0..4020005]of double;
f:array[0..2005]of longint;
net,mc:array[1..3]of longint;
i,j,k,l,r,n,m,mid,x,z:longint;
xx,ke:double;
procedure qsort(l,r:longint);
var
i,j:longint;
mid:double;
begin
i:=l;
j:=r;
mid:=ju[(i+j) div 2];
repeat
while ju[i]<mid do inc(i);
while ju[j]>mid do dec(j);
if i<=j then
begin
ju[0]:=ju[i];
ju[i]:=ju[j];
ju[j]:=ju[0];
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
function gcd(x,y:longint):longint;
begin
if y=0 then exit(x) else exit(gcd(y,x mod y));
end;
begin
//assign(input,'t2.in'); reset(input);
readln(n,m);
for i:=1 to n do readln(a[i,1],a[i,2],a[i,3]);
{for i:=0 to n-1 do
for j:=i+1 to n do
begin
x:=sqr(a[i,2]-a[j,2])+sqr(a[i,3]-a[j,3]);
if x=0 then continue;
for l:=trunc(sqrt(x)) downto 1 do
if x mod (sqr(l))=0 then break;
cc[i,j,1]:=l;
cc[i,j,2]:=x div (sqr(l));
cc[i,j,3]:=a[j,1]-a[i,1];
z:=gcd(cc[i,j,1],cc[i,j,3]);
cc[i,j,1]:=cc[i,j,1] div z;
cc[i,j,3]:=cc[i,j,3] div z;
end; }

x:=0;
for i:=0 to n-1 do
for j:=i+1 to n do
begin
inc(x);
ju[x]:=sqrt(sqr(a[j,2]-a[i,2])+sqr(a[j,3]-a[i,3]))/(a[j,1]-a[i,1]);
fe[i,j]:=ju[x];
end;
qsort(1,x);
l:=1;
r:=x;
while l<r do
begin
mid:=(l+r) div 2;
xx:=ju[mid];
ke:=0;
fillchar(f,sizeof(f),0);
for i:=1 to n do
for j:=0 to i-1 do
if fe[j,i]<=xx then
begin
if f[j]+1>f[i] then f[i]:=f[j]+1;
if fe[j,i]>ke then
begin
net[1]:=j;
net[2]:=i;
ke:=fe[j,i];
end;
end;
k:=0;
for i:=1 to n do
if f[i]>k then k:=f[i];
if k>=m then r:=mid else l:=mid+1;
end;
xx:=ju[l];
ke:=0;
fillchar(f,sizeof(f),0);
for i:=1 to n do
for j:=0 to i-1 do
if fe[j,i]<=xx then
begin
if f[j]+1>f[i] then f[i]:=f[j]+1;
if fe[j,i]>ke then
begin
net[1]:=j;
net[2]:=i;
ke:=fe[j,i];
end;
end;
i:=net[1];
j:=net[2];
x:=sqr(a[i,2]-a[j,2])+sqr(a[i,3]-a[j,3]);
for l:=trunc(sqrt(x)) downto 1 do
if x mod (sqr(l))=0 then break;
cc[i,j,1]:=l;
cc[i,j,2]:=x div (sqr(l));
cc[i,j,3]:=a[j,1]-a[i,1];
z:=gcd(cc[i,j,1],cc[i,j,3]);
cc[i,j,1]:=cc[i,j,1] div z;
cc[i,j,3]:=cc[i,j,3] div z;
writeln(cc[i,j,1],' ',cc[i,j,2],' ',cc[i,j,3]);
//close(input);
end.