HDU Dwarven Sniper’s hunting

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <algorithm>
//#include "myAlgorithm.h"

#define MAX 1000005
#define OFFENCE (1e9 + 5)
#define INF (1e8 + 5)
#define eps 1e-9
#define Rep(s, e) for( int i = s; i <= e; i++)
#define Cep(e, s) for( int i = e; i >= s; i --)
#define PI acos(-1.0)
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;
/**
    原想想到得到个方程, 然后再二三分或者解方程, 但只要有单调的地方就有二分, 学习了~
    设L走了t0时间之后, D开枪; (因为D比L快, 子弹比L快, 所以, 肯定能找到一个点使得子弹走完最大长度)
    则D会射中在P(Lx * (t0 + L/vB)+ x1, Ly * (t0 + L/vB) + y1)的L, 此时D在以P为圆心的圆上, D走了vD * t0, 为了使
    t0尽量小, D应该选择PD方向走, 也就是在半径方向上, 于是就有

    vD * t0 = (len(PD) - L || L - len(PD)),
    由D和圆的位置推出t0是多是少,  单调逼近min(t0), 使得D在圆上
    由此可以二分枚举t0;

    总时间还要+上tB
    精度1e-9可以AC, 太低会wa

*/
double xd, yd, x2, y2, Vx, Vy, vd, vb, L;
void solve()
{
    double l = 0, r = OFFENCE, mid;
    double tB = L/vb;
    while(r - l > eps){
        //cout<<"ff"<<endl;
        mid = (l + r)/2.0;
        //cout<<mid<<endl;
        double PDx = Vx * (mid + tB) + xd - x2, PDy = Vy * (mid  + tB) + yd - y2;
        double lenPD = sqrt( PDx * PDx + PDy * PDy);
        double lenDt0 = vd * mid;
        if(lenPD >= L){///
            if(lenPD - L > lenDt0){///园外, 时间不够
                l = mid;
            }else {
                r = mid;
            }
        }else {
            if(L - lenPD > lenDt0){///园内, 时间不够
                l = mid;
            }else {
                r = mid;
            }
        }
    }
    printf("%.3f %.3f\n", L,  mid + tB);///总时间
}
int main(){
    while(cin>>xd>>yd>>x2>>y2>>Vx>>Vy>>vd>>vb>>L){
        if(!xd && !yd && !x2 && !y2 && !Vx && !Vy && !vd &&!vb && !L)break;
        solve();
    }
    return 0;
}
/*
-1 0 0 10 1 0 2 10 10
0 0 0 5 0 1 2 6 6
0 0 0 0 0 0 0 0 0
*/



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值