1060 - Collecting Luggage

Collecting your luggage after a flight can be far from trivial. Suitcases and bags appear on a conveyor belt, and hundreds of passengers fight for a good vantage point from which to find and retrieve their belongings. Recently, the Narita Airport Authority has decided to make this process more efficient. Before redesigning their baggage claim areas, they need a simulation program to determine how average passengers behave when collecting their luggage. This simulation assumes that passengers will always take a path of straight line segments to reach their luggage in the least amount of time.

For this problem, a conveyor belt is modeled as a simple polygon. A luggage piece appears on some point of the conveyor belt, and then moves along the conveyor belt at a constant speed. A passenger is initially positioned at some point outside the conveyor belt polygon. As soon as the piece of luggage appears, the passenger moves at a constant speed (which is greater than the speed of the luggage piece) in order to pick up the luggage. The passenger's path, which may not cross over the conveyer belt but may touch it, puts the passenger in the same position as the moving piece of luggage in the least amount of time.

In the following figure, the conveyor belt is depicted as a polygon ABCDEF. The luggage starts at the top-left corner (Point A) and moves in counterclockwise direction around the polygon as shown with the small arrows. The passenger begins at point P and moves on the path that puts him and the luggage into the same place (point M in the figure) in the shortest amount of time. The passenger's path is shown by a red arrow. This figure corresponds to the first sample input.

\epsfbox{p2397.eps}

Input 

The input consists of one or more test cases describing luggage pickup scenarios. A scenario description begins with a line containing a single integer N (3$ \le$N$ \le$100) , the number of vertices of the conveyor belt polygon. This is followed by N lines, each containing a pair of integers xi , yi (| xi|,| yi|$ \le$10000) giving the coordinates of the vertices of the polygon in counterclockwise order. The polygon is simple, that is, it will not intersect itself and it will not touch itself. The polygon description is followed by a line containing two integers px , py (| px|,| py|$ \le$10000) , the coordinates of the starting position of the passenger. The last line of the description contains two positive integers VL and VP (0 < VL < VP$ \le$10000) , which are the speed of the luggage and the passenger respectively. All the coordinates are given in meters, and the speeds are given in meters per minute.

You can assume that the passenger is positioned outside the conveyor belt polygon. The luggage will move in counterclockwise direction around the conveyor belt, starting at the first vertex of the polygon.

The input is terminated by a line containing a single integer zero.

Output 

For each test case, print a line containing the test case number (beginning with 1) followed by the minimum time that it takes the passenger to reach the luggage. Use the formatting shown in the sample output (with minutes and seconds separated by a colon), rounded to the nearest second. The value for seconds should be printed in a field of width two (padded with leading zeroes if required).

Sample Input 

6 
0 40 
0 0 
20 0 
20 20 
40 20 
40 40 
120 40 
70 100 
4
0 0 
10 0 
10 10 
0 10 
100 100 
10 11 
0

Sample Output 

Case 1: Time = 1:02 
Case 2: Time = 12:36







#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int n,i,j,x[101],y[101],mark[102],px,py,vl,vp,cases,ans;
double C,d,l,r,m,t,map[102][102],len[102];
double dis(double dx,double dy)
{
	return sqrt(dx*dx+dy*dy);
}

int cross(double xa,double ya,double xb,double yb,double xc,double yc,double xd,double yd)
{
	if(xa<xc&&xb<xc&&xa<xd&&xb<xd)
		return 0;
	if(ya<yc&&yb<yc&&ya<yd&&yc<yd)
		return 0;
	if(xa>xc&&xb>xc&&xa>xd&&xb>xd)
		return 0;
	if(ya>yc&&yb>yc&&ya>yd&&yb>yd)
		return 0;
	double cra,crb;
	cra=(xb-xa)*(yc-ya)-(yb-ya)*(xc-xa);
	crb=(xb-xa)*(yd-ya)-(yb-ya)*(xd-xa);
	if(cra*crb>0)
		return 0;
	cra=(xd-xc)*(ya-yc)-(yd-yc)*(xa-xc);
	crb=(xd-xc)*(yb-yc)-(yd-yc)*(xb-xc);
	if(cra*crb>0)
		return 0;
	return 1;
}

int in_shape(double ox,double oy)
{
	int i,c;
	c=0;
	for(i=0;i<n;i++)
		c+=cross(ox,oy,98765,43210,x[i],y[i],x[i+1],y[i+1]);
	return c&1;
}

int no_cross(double xa,double ya,double xb,double yb)
{
	int i;
	if(in_shape((xa+xb)/2,(ya+yb)/2))
		return 0;
	xa=xa*(1-1e-7)+xb*1e-7;
	ya=ya*(1-1e-7)+yb*1e-7;
	xb=xb*(1-1e-7)+xa*1e-7;
	yb=yb*(1-1e-7)+ya*1e-7;
	for(i=0;i<n;i++)
		if(cross(xa,ya,xb,yb,x[i],y[i],x[i+1],y[i+1]))
			return 0;
	return 1;
}

double best_path()
{
	double s,lx,ly,bl,tl;
	int i,j,bj;
	s=m*vl;
	s-=int(s/C)*C;
	for(i=0;i<n;i++)
	{
		if(s<map[i][(i+1)%n])
			break;
		s-=map[i][(i+1)%n];
	}
	d=map[i][(i+1)%n];
	lx=x[i]*(d-s)/d + x[(i+1)%n]*s/d;
	ly=y[i]*(d-s)/d + y[(i+1)%n]*s/d;
	if(no_cross(px,py,lx,ly))
		return dis(px-lx,py-ly);
	j=i;
	for(i=0;i<n;i++)
	{
		if(i==j||i==(j+1)%n||no_cross(lx,ly,x[i],y[i]))
		{
			map[n][i]=dis(lx-x[i],ly-y[i]);
			map[i][n]=map[n][i];
		}
		else
		{
			map[n][i]=-2;
			map[i][n]=-2;
		}
		if(no_cross(px,py,x[i],y[i]))
		{
			map[n+1][i]=dis(px-x[i],py-y[i]);
			map[i][n+1]=map[n+1][i];
		}
		else
		{
			map[n+1][i]=-2;
			map[i][n+1]=-2;
		}
		len[i]=1e9;
	}
	len[n]=1e9;
	len[n+1]=0;
	memset(mark,0,sizeof(mark));
	for(i=0;i<=n;i++)
	{
		bl=1e9;
		for(j=0;j<n+2;j++)
			if(!mark[j]&&len[j]<bl)
			{
				bl=len[j];
				bj=j;
			}
		mark[bj]=1;
		for(j=0;j<=n;j++)
			if(!mark[j]&&map[bj][j]>-1)
			{
				tl=bl+map[bj][j];
				if(tl<len[j])
					len[j]=tl;
			}
	}
	return len[n];
}

int main()
{
	while(scanf("%d",&n)&&n)
	{
		for(i=0;i<n+2;i++)
			for(j=0;j<n+2;j++)
				map[i][j]=-2;
		for(i=0;i<n;i++)
			scanf("%d%d",&x[i],&y[i]);
		x[n]=x[0];
		y[n]=y[0];
		C=0;
		for(i=0;i<n;i++)
		{
			d=dis(x[i]-x[i+1],y[i]-y[i+1]);
			C+=d;
			map[i][(i+1)%n]=d;
			map[(i+1)%n][i]=d;
		}
		for(i=0;i<n-2;i++)
			for(j=i+2;j<n;j++)
				if(no_cross(x[i],y[i],x[j],y[j]))
				{
					map[i][j]=dis(x[i]-x[j],y[i]-y[j]);
					map[j][i]=map[i][j];
				}
		scanf("%d%d%d%d",&px,&py,&vl,&vp);
		l=0;
		r=1e8;
		while(r-l>1e-8)
		{
			m=(l+r)/2;
			t=best_path()/vp;
			if(t<m)
				r=m;
			else
				l=m;
		}
		ans=int(m*60+0.5);
		printf("Case %d: Time = %d:%02d\n",++cases,ans/60,ans%60);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值