JZOJ 4783. Osu

来源:互联网 发布:验证dss算法的有效性 编辑:程序博客网 时间:2024/05/05 07:05

Problem

Description

这里写图片描述

Input

这里写图片描述

Output

这里写图片描述

Sample Input

4 2
1 2 2
2 0 2
3 0 0
4 2 0

Sample Output

1 2 1

Hint

圆圈只在出现的时刻有效。即:时刻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

这里写图片描述

Solution

我们发现题目要求“最大值最小”,所以我们要想到二分。
然后通过DP算路径(路径用一个数组存),然后找最大值就行了。
DP时间复杂度:O(n2)
其实求a,b,c没有想象中的这么难。
我们将b的根号拆开,然后将b中质因数x的指数为2n的统统去掉,然后a=axn
然后a与c再约分就行了。

Code

#include<iostream>#include<cstdio>#include<cmath>#include<cstring> #define N 2010#define fo(i,a,b) for(i=a;i<=b;i++)#define LF doubleusing namespace std;LF dis[N][N],l,r,mid,ans,t[N],x[N],y[N];int a,b,c,d,n,i,j,k,m,A1,A2,f[N],pred[N];int gcd(int x,int y){    if (y==0) return x;else return gcd(y,x%y);}int main(){    scanf("%d%d",&n,&k);    fo(i,1,n) scanf("%lf%lf%lf",&t[i],&x[i],&y[i]);    fo(i,0,n-1)        fo(j,i+1,n)            dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))/(t[j]-t[i]);    l=0;    r=100000000;    while (r-l>0.001)    {        bool p=0;        mid=(l+r)/2;        memset(f,0,sizeof(f));        ans=0;        fo(i,0,n)        {            fo(j,0,i-1)                if (dis[j][i]<=mid && f[j]+1>f[i])                {                    f[i]=f[j]+1;                    pred[i]=j;                }            if (f[i]==k)            {                for (m=i;m;m=pred[m])                {                    if (dis[pred[m]][m]>ans)                    {                        A1=pred[m];                        A2=m;                        ans=dis[pred[m]][m];                    }                }                p=1;                break;            }        }        if (p) r=mid;else l=mid;    }    a=1;    b=(x[A1]-x[A2])*(x[A1]-x[A2])+(y[A1]-y[A2])*(y[A1]-y[A2]);    c=t[A2]-t[A1];    fo(i,2,sqrt(b))        while (b%(i*i)==0)        {            a=a*i;            b=b/(i*i);        }    d=gcd(a,c);    a/=d;c/=d;    printf("%d %d %d",a,b,c);}
3 0