题目链接:http://poj.org/problem?id=3029
题意:有个n个旅客的旅游团,到了旅客上车的时间,给出各个旅客的位置、运动方向和速度,问导游以v的速度从原点出发,把所有旅客召回在原点的
车所需的最短时间.其中,如果导游追到旅客,则旅客以其速度直线向原点进发,所求的结果是最后到达原点的游客距离导游从原点出发的最短的时间.
解题:题目给出的数据量不大,所以可以枚举出所有导游追到游客的顺序,再在这些不同的顺序中找到一个最短的时间,就是所求答案.
题目用到余弦定理,花了好久才推出来,这个编程不能怕麻烦啊~囧~
#include<stdio.h> #include<string.h> #include<math.h> #define M 8 const double eps=1e-8; const double inf=10e12; const double Pi=acos(-1); typedef struct talPoint{ double x,y; talPoint(){} talPoint(double x,double y) { this->x=x;this->y=y; } }Point; typedef struct{ Point p; double v; double dir; }Guest; Guest g[M],f[M]; Guest o; bool mark[M]; double anst; int stk[M],top; int n; double Max(double a,double b) { return a>b?a:b; } double Dis(Point p,Point q) { p.x-=q.x,p.y-=q.y; return sqrt(p.x*p.x+p.y*p.y); } double Dis(Point p) { return sqrt(p.x*p.x+p.y*p.y); } /* Point Fix(Point pl,Point pr,Point ql,Point qr) {//用两点表示的两条直线的交点 Point ret; ret.x=(pl.y-ql.y)*(qr.x-ql.x)*(pr.x-pl.x) + ql.x*(qr.y-ql.y)*(pr.x-pl.x) - pl.x*(pr.y-pl.y)*(qr.x-ql.x); ret.x/=(qr.y-ql.y)*(pr.x-pl.x)-(pr.y-pl.y)*(qr.x-ql.x); ret.y=(pr.y-pl.y)*(ret.x-pl.x)/(pr.x-pl.x)+pl.y; return ret; } Point MissPoint(Guest p) {//刚开始思路就错了~ Point tmp; double tdir; tmp.x=(p.p.x*o.v-o.p.x*p.v)/(o.v-p.v); tmp.y=(p.p.y*o.v-o.p.y*p.v)/(o.v-p.v); tdir=atan2(p.p.y-o.p.y,p.p.x-o.p.x); tdir+=Pi*0.5; return Fix(tmp,talPoint(tmp.x+cos(tdir),tmp.y+sin(tdir)), p.p,talPoint(p.p.x+cos(p.dir),p.p.y+sin(p.dir))); } */ void CallWork() { int i; Point next; double tmpt,curt; double t1,t2; double a,b,c,cosa,d; Point e,h; tmpt=0;curt=0; o.p.x=o.p.y=0.0; memmove(g,f,sizeof(f)); for(i=0;i<top;i++){ g[stk[i]].p.x+=curt*g[stk[i]].v*cos(g[stk[i]].dir); g[stk[i]].p.y+=curt*g[stk[i]].v*sin(g[stk[i]].dir); //next=MissPoint(g[stk[i]]); //t1=Dis(next,o.p)/o.v; //t2=Dis(next,talPoint(0,0))/g[stk[i]].v; //curt+=t1; //o.p=next; //用点积求出夹角A,然后根据两条边的比例,用余弦定理求出t h.x=g[stk[i]].v*cos(g[stk[i]].dir); h.y=g[stk[i]].v*sin(g[stk[i]].dir); e.x=g[stk[i]].p.x-o.p.x; e.y=g[stk[i]].p.y-o.p.y; cosa=(e.x*h.x+e.y*h.y)/(g[stk[i]].v*Dis(e)); d=Dis(e); //联立求得一关于时间的一元二次议程,下面为求议程解 a=(o.v*o.v-g[stk[i]].v*g[stk[i]].v); b=2*g[stk[i]].v*d*cosa; c=d*d; t1=(b+sqrt(b*b+4*a*c))/(2*a); next.x=g[stk[i]].v*t1*cos(g[stk[i]].dir)+g[stk[i]].p.x; next.y=g[stk[i]].v*t1*sin(g[stk[i]].dir)+g[stk[i]].p.y; t2=Dis(next)/g[stk[i]].v; curt+=t1; o.p=next; if(curt+t2>anst) return; tmpt=Max(curt+t2,tmpt); } if(tmpt<anst) anst=tmpt; } void Dfs() { int i; if(top==n){ CallWork(); return; } for(i=0;i<n;i++){ if(mark[i]) continue; mark[i]=true; stk[top++]=i; Dfs();top--; mark[i]=false; } } int main() { int i; while(scanf("%d",&n),n){ scanf("%lf",&o.v); for(i=0;i<n;i++){ scanf("%lf%lf%lf%lf",&f[i].p.x, &f[i].p.y,&f[i].v,&f[i].dir); } anst=inf;top=0; Dfs(); printf("%.0f/n",anst); } return 0; }