hdu_4170 Supply Mission (计算几何)

http://acm.hdu.edu.cn/showproblem.php?pid=4170

题意:
飞机在位置(x0,y0),飞行速度为v km/h,有N(0<N<8)艘船分别为(xi,yi)速度向量为(vxi,vyi) km/h,坐标单位为km 
飞机必须在每艘船上要一小时卸载货物,最后飞回原来的位置(x0,y0),求最少时间花费,用时分秒输出。 
思路:
想了会儿,没什么思路,看了看数据范围,N最大才8,时限10秒,完全可以暴力嘛。
直接把到达船的顺序做个全排列,取最小的一次时间就行了,算相遇时要一定要细心。
还有个小trick,秒进位后等于60,这里搞了我好久好久。。。 

/*
program:hdu_4170 & hunnu_11215
author:BlackAndWhite
*/
#include<stdio.h>
#include<math.h>
#include<algorithm>
#define eps 1e-6
using namespace std;
struct point
{
    int x,y;
}a[10],v[10],s;
double t,ans;
int N,sv,i,p[10],T[3],js=1;
double crosstime(double x0,double y0,double v0,double x1,double y1,double vx,double vy)
{//表示飞机在(x0,y0),速度为v0,要与船(x1,y1)速度向量为(vx,vy)相遇所花费的时间。 
    double a,b,c,t;
    a=vx*vx+vy*vy-v0*v0;
    b=2*(vx*(x1-x0)+vy*(y1-y0));
    c=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
    if(a<eps&&a>-eps) return -c/b;
    if(a<eps) {a=-a;b=-b;c=-c;}
    return (-b+sqrt(b*b-4*a*c))/(2*a);
}
double back(double x0,double y0,double x1,double y1,double sv)//最后回到起点的时间花费 
{
    return sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0))/sv;
}
void trs(double ans,int T[3])//小数形式转换为时分秒 
{
    T[0]=(int)ans;
    ans-=T[0];
    T[1]=(int)(ans*=60.0);ans-=T[1];
    T[2]=(int)(ans*60.0+0.9999999);
    if(T[2]==60) {T[2]=0;T[1]++;}//trick,进位啊。。。 
    if(T[1]==60) {T[1]=0;T[0]++;}
}
int main()
{
    while(scanf("%d",&N),N)
    {
        for(i=0;i<N;i++) scanf("%d%d%d%d",&a[i].x,&a[i].y,&v[i].x,&v[i].y);
        scanf("%d%d%d",&s.x,&s.y,&sv);
        for(i=0;i<=N;i++) p[i]=i;
        ans=1e9;
        do
        {
            t=crosstime(s.x*1.0,s.y*1.0,sv*1.0,a[p[0]].x,a[p[0]].y,v[p[0]].x,v[p[0]].y)+1.0;
            for(i=1;i<N;i++)//当前在p[i-1]船上准备出发瞬间,p[i-1]船已经行驶t小时 ,p[i]船同样行驶t小时 
                t+=1.0+crosstime(a[p[i-1]].x*1.0+t*v[p[i-1]].x,a[p[i-1]].y*1.0+t*v[p[i-1]].y,sv*1.0,a[p[i]].x*1.0+t*v[p[i]].x,a[p[i]].y*1.0+t*v[p[i]].y,v[p[i]].x*1.0,v[p[i]].y*1.0);
            t+=back(a[p[N-1]].x*1.0+t*v[p[N-1]].x,a[p[N-1]].y*1.0+t*v[p[N-1]].y,s.x,s.y,sv);
            if(t<ans) ans=t;
        }
        while(next_permutation(p,p+N));
        trs(ans,T);
        printf("Case %d: %d hour(s) %d minute(s) %d second(s)\n",js++,T[0],T[1],T[2]);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值