考试题T3

捕获.PNG
捕获2.PNG

题意分析

这题一看没有什么思路

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

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

就是跑了一个区间

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

5cb1d2f3b055a.png

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

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

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

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


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

\[\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;
}

转载于:https://www.cnblogs.com/LovToLZX/p/10702745.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值