zoukankan      html  css  js  c++  java
  • 【BZOJ2710】[Violet 1] 追风者(计算几何)

    点此看题面

    大致题意: 有两个点,一个在一条线段上匀速来回运动,一个在一条射线上保持匀速运动,求两点最短距离(d)

    前言

    我觉得我根本不是做几何题的料,这种题目想+码+调一共花了(3)个小时。。。

    大致思路

    龙卷风?这不是初中数学的二次函数题目嘛!于是我推了半天式子,最后发现超级复杂而且还超级恶心。

    实际上,我们可以把一个点的运动转移到另一个点上,那么就变成了一个定点和一个动点的距离问题。

    然后考虑此时动点相当于是在做折线运动,其中可以分为两组平行线,则我们可以分别考虑定点到这两组平行线的距离。

    而对于这个东西,可以使用三分,即三分这是第几条折线。

    大致思路就这么简单。

    千万千万注意,这是点到线段的距离,而不是点到直线的距离!就为了这个调了一个小时。。。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define DB long double
    #define INF 1e18
    #define eps 1e-8
    using namespace std;
    DB v1,v2,d1,d2;
    struct P
    {
    	DB x,y;I P(Con DB& a=0,Con DB& b=0):x(a),y(b){}
    	I P operator + (Con P& o) Con {return P(x+o.x,y+o.y);}
    	I P operator - (Con P& o) Con {return P(x-o.x,y-o.y);}
    	I P operator * (Con DB& v) Con {return P(x*v,y*v);}
    	I P operator / (Con DB& v) Con {return P(x/v,y/v);}
    	I DB operator * (Con P& o) Con {return x*o.x+y*o.y;}
    	I DB operator ^ (Con P& o) Con {return x*o.y-y*o.x;}
    }p,k,s,t;typedef P Vec;
    I void Gmin(DB& x,Con DB& y) {x>y&&(x=y);}
    #define L(A) sqrt((A).x*(A).x+(A).y*(A).y)
    I DB D(Con P& s,Con P& A,Con P& B)//点到线段距离
    {
    	if(((s-A)*(B-A))<0||((s-B)*(A-B))<0) return min(L(s-A),L(s-B));//垂足不在线段上
    	return fabs((s-A)^(s-B))/L(A-B);//点到直线距离
    }
    int main()
    {
    	W(cin>>p.x>>p.y>>k.x>>k.y>>v1>>s.x>>s.y>>t.x>>t.y>>v2>>d1>>d2)
    	{
    		Vec V1=k-p;V1=V1/L(V1)*v1;Vec V2=t-s;V2=V2/L(V2)*v2;//计算速度
    		RI i,l,r,m1,m2;DB d=INF,ti=L(t-s)/v2;
    		P u=p+(V1-V2)*ti,w=u+(V1+V2)*ti,g=V1*(2*ti);//u,w为折点,g为折一轮坐标总变化量
    		l=0,r=1e9;W(r-l>12) m1=l+(r-l)/3,m2=l+2LL*(r-l)/3,//三分
    			D(s,p+g*m1,u+g*m1)<=D(s,p+g*m2,u+g*m2)?r=m2:l=m1;
    		for(i=l;i<=r;++i) Gmin(d,D(s,p+g*i,u+g*i));//更新答案
    		l=0,r=2e9;W(r-l>12) m1=l+(r-l)/3,m2=l+2LL*(r-l)/3,//三分
    			D(s,u+g*m1,w+g*m1)<=D(s,u+g*m2,w+g*m2)?r=m2:l=m1;
    		for(i=l;i<=r;++i) Gmin(d,D(s,u+g*i,w+g*i));//更新答案
    		puts(d<=d1?"Dangerous":(d<=d2?"Perfect":"Miss"));//判断输出答案
    	}return 0;
    }
    
  • 相关阅读:
    指针问题,p+i什么意思i代表什么
    怎么用C语言写一个飞机程序
    switch()语句中()中必须是常量吗
    一元二次方程运行结果中输入上系数后总显示输入不合法无论系数可以得出实根
    我想学号图论求大神请教
    c-freelib库
    十进制转十六进制问题(有代码)
    关于逐个读取同一目录下txt文本的问题
    JAVA-JDK1.7-ConCurrentHashMap-测试和验证
    JAVA-JDK1.7-ConCurrentHashMap-源码并且debug说明
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2710.html
Copyright © 2011-2022 走看看