考试题T3

捕获.PNG
捕获2.PNG

题意分析

这题一看没有什么思路

幸好我们机房的红太阳\(ghj1222\)切了这道题

首先我们考虑风跑一个来回之后人怎么样

就是跑了一个区间

也就是风跑了若干个来回之后 人跑了若干个区间

所以我们考虑求出距离最小的那个区间

距离是一个单峰函数 所以我们用三分

然后的话 问题就是求两条有向线段之间的最小距离

这也是一个单峰函数 所以我们用三分


我们需要处理出来风从一头走到另一头的人的走的向量

\[\frac{\overrightarrow{v}}{|\overrightarrow{v}|}\frac{v_w}{v_t}dis \]

$dis: $风走的距离

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#define ll long long
#define inf 0x7fffffff
#define N 500008
#define IL inline
#define M 1008611
#define D double
#define eps 1e-7
#define R register
using namespace std;
template<typename T>IL void read(T &_)
{
    T __=0,___=1;char ____=getchar();
    while(!isdigit(____)) {if(____=='-') ___=0;____=getchar();}
    while(isdigit(____)) {__=(__<<1)+(__<<3)+____-'0';____=getchar();}
    _=___ ? __:-__;
}
/*-------------OI使我快乐-------------*/
struct Node
{
	D xx,yy;
	friend Node operator +(const Node &A,const Node &B)
	{return (Node){A.xx+B.xx,A.yy+B.yy};}
	friend Node operator -(const Node &A,const Node &B)	
	{return (Node){A.xx-B.xx,A.yy-B.yy};}
	friend Node operator *(const Node &A,const D &B)
	{return (Node){A.xx*B,A.yy*B};}
	friend Node operator /(const Node &A,const D &B)
	{return (Node){A.xx/B,A.yy/B};}
}fro_x,to_x,fro_y,to_y,tmp;
D v_x,v_y,d_x,d_y;
IL D qury_dis(Node now)
{return sqrt((now.xx*now.xx)+(now.yy*now.yy));}
IL D qury_ans(const Node &sx,const Node &tx,const Node &sy,const Node &ty)
{//三分最小的距离
	Node tmpx=tx-sx,tmpy=ty-sy;    
	D le=0,ri=1,ans=0;
	while((ri-le)>eps)
	{
		D mid=(ri-le)/3.0+le,mmid=ri-(ri-le)/3.0;
		Node cdy,wzy,zjz,ghj;
		cdy=sx+tmpx*mid;wzy=sy+tmpy*mid;
		zjz=sx+tmpx*mmid;ghj=sy+tmpy*mmid;
//这里要注意的是 二者的进行是等比例的      
		D dis_cdy=qury_dis(wzy-cdy),dis_wzy=qury_dis(ghj-zjz);
		if(dis_cdy>dis_wzy) le=mid,ans=dis_wzy;
		else ri=mmid,ans=dis_cdy;
	}
	return ans;
}
IL D work(ll now)
{
	Node cdy,wzy,zjz;
	cdy=fro_x+tmp*now*2;wzy=cdy+tmp;zjz=wzy+tmp;
	return min(qury_ans(cdy,wzy,fro_y,to_y),qury_ans(wzy,zjz,to_y,fro_y));
}
int main()
{
	freopen("chaser.in","r",stdin);
	freopen("chaser.out","w",stdout);
	while(scanf("%lf%lf",&fro_x.xx,&fro_x.yy)!=EOF)
	{
		scanf("%lf%lf%lf",&to_x.xx,&to_x.yy,&v_x);
		scanf("%lf%lf%lf%lf%lf",&fro_y.xx,&fro_y.yy,&to_y.xx,&to_y.yy,&v_y);
		tmp=((to_x-fro_x)/qury_dis(to_x-fro_x)*v_x/v_y*qury_dis(to_y-fro_y));
//相当于是风跑一个来回之后    
//人在其方向上走的向量    
//		printf("now is %.2f %.2f\n",tmp.xx,tmp.yy);
		scanf("%lf%lf",&d_x,&d_y);
//三分区间对应的位置       
		ll le=0,ri=1e13;
		while(ri-le>=5)
		{
//ghj1222说 整数三分卡边界比较恶心 所以设置一个误差 然后暴力求就可以了
			ll mid=(ri-le)/3+le,mmid=ri-(ri-le)/3;
			D resa=work(mid),resb=work(mmid);
			if(resa>resb) le=mid;
			else ri=mmid;
		}
		D ans=1e18;
		for(R ll i=le;i<=ri;++i)
		ans=min(ans,work(i));
		if(ans<d_x) puts("Dangerous");
		else if(ans>=d_x&&ans<=d_y) puts("Perfect");
		else puts("Miss");
	}
	fclose(stdin);
	fclose(stdout);
    return 0;
}

posted @ 2019-04-13 20:27  tcswuzb  阅读(143)  评论(0编辑  收藏  举报