HDU 4024 Dwarven Sniper’s hunting【水二分】

HDU 4024 Dwarven Sniper’s hunting【水二分】

这。。。。。这题难道自带“错误题意引导”???为啥我就算读对了题意,想对了做法,结果敲的时候又按照错误的想法敲了呢?伤不起。。
其实04题才是本场最水题,但是- -题意太坑爹了。唉。

题意:
二维平面追击。
被追击的人有起始坐标,有一个速度矢量,从开始就一直在走。
追击者有起始坐标,有运动速率,射出的子弹也有一个速率。子弹有一个有效射击半径。
就问,在子弹飞行距离最远的情况下,让总追击时间(被追击者被击中前的运动时间)最短,最远距离是多少,最短时间是多少。(一直搞反了题意。妹的。)
条件保证,1e9的时间内一定有解,被追者速率<追者速率<子弹速率。
第二个条件保证了,时间短的时候打不中的话,将时间拉长就一定能打中。
做法:
由于一定有解,为了让飞行距离最长,那么就让它等于射击半径。
果断二分总时间。
得出被追者当前坐标,算出与追击者起始坐标的距离。以射击半径画圆,判断追击者是在圆内还是圆外。并算出小圆半径(即去除子弹时间的剩余时间乘以追击者的运动速率)。判断两圆状态,相离或相切则l = mid,相交则r=mid。(前者表示打不着还需要继续跑,后者表示打到了但不是最优所以要缩短)。
二分中间的某些状态大概可以表示追击者跑到某个地方停了下来,然后等被追击者跑到指定位置再开始秀枪法;但鉴于最优解一定不需要让追击者有等待时间,所以最后的最优状态一定是相切的。
话说因为不小心用到了除法,所以eps开到1e-6会被卡精度,所以没办法只能1e-8了。。第一次写的时候开到1e-6竟然连样例都有精度差,这。。。

唉,被题意坑啊,自己脑子笨,想不清楚二分啊,我弱爆了。

附代码:
#include  < iostream >
#include 
< cstdio >
#include 
< cstring >
#include 
< cmath >
using   namespace  std;
const   double  eps  =  1e - 6 ;
const   double  inf  =  1e9;
int  comp( double  x)
{
    
if (fabs(x)  <  eps)
        
return   0 ;
    
else   if (x  <   - eps)
        
return   - 1 ;
    
else
        
return   1 ;
}
struct  point
{
    
double  x,y;
    point(){}
    point(
double  a, double  b):x(a),y(b){}
    point 
operator   -  ( const  point p)
    {
        
return  point(x  -  p.x,y  -  p.y);
    }
    point 
operator   * ( const   double  a)
    {
        
return  point(x  *  a,y  *  a);
    }
    point 
operator   + ( const  point p)
    {
        
return  point(x  +  p.x,y  +  p.y);
    }
    
double  norm()
    {
        
return  sqrt(x  *  x  +  y  *  y);
    }
}p1,p2,L;
double  vd,vb,limit;
int  main()
{
    
while (scanf( " %lf %lf %lf %lf %lf %lf %lf %lf %lf " , & p1.x, & p1.y, & p2.x, & p2.y, & L.x, & L.y, & vd, & vb, & limit)  ==   9 )
    {
        
if ( ! comp(p1.x)  &&   ! comp(p1.y)  &&   ! comp(p2.x)  &&   ! comp(p2.y)  &&   ! comp(L.x)  &&   ! comp(L.y)  &&   ! comp(vd)  &&   ! comp(vb)  &&   ! comp(limit))
            
break ;
        
double  t2  =  limit  /  vb;
        
double  l  =   0.0 ,r  =  inf,mid;
        
while (comp(l  -  r)  <   0 )
        {
            mid 
=  (l  +  r)  /   2.0 ;
            point now 
=  p1  +  L  *  mid;
            
if (comp(t2  -  mid)  >   0 )
            {
                l 
=  mid;
                
continue ;
            }
            
double  d  =  (now  -  p2).norm();
            
double  most  =  (mid  -  t2)  *  vd;
            
if (comp(d  -  limit)  <=   0 )
            {
                
if (comp(d  +  most  -  limit)  <   0 )
                    l 
=  mid;
                
else
                    r 
=  mid;
            }
            
else
            {
                
if (comp(most  +  limit  -  d)  <   0 )
                    l 
=  mid;
                
else
                    r 
=  mid;
            }
        }
        printf(
" %.3lf %.3lf\n " ,limit,mid);
    }
}
å

你可能感兴趣的:(HDU 4024 Dwarven Sniper’s hunting【水二分】)