【NOIP2016提高A组模拟9.15】Osu

6 篇文章 0 订阅

题目

这里写图片描述
Input
这里写图片描述

Sample Input

4 2
1 2 2
2 0 2
3 0 0
4 2 0
Output
这里写图片描述
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
这里写图片描述

比赛时の想法

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.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值