您的位置:首页 > 其它

GYM 101147 B.Street(Floyd)

2017-03-21 19:01 316 查看
Description

一个l*u的区域,里面有一些遮阳棚,现在要从下底边跑到上底边,起点终点位置任意,只要起点在下底边终点在上底边即可,问暴露在太阳下的最短距离是多少

Input

第一行一整数T表示用例组数,每组用例首先输入三整数n,l,u分别表示遮阳棚数量,区域的长和宽,之后n行每行输入四个整数h,w,d,k,h和w表示该遮阳棚的长和宽,d表示该遮阳棚下底边和该区域下底边的距离,k表示该遮阳棚和该区域的左边或者左边相邻(0表示和左边相邻,1表示和右边相邻)(1<=n<=100,1<=l,u,h,w,d,k<=1e9,保证遮阳棚均在该区域内,且任意两个遮阳棚不会有重叠区域)

Output

输出从下底边跑到上底边暴露在太阳下的最短距离

Sample Input

2

1 200 100

10 50 50 0

4 200 100

20 10 10 1

80 20 20 0

20 90 120 0

30 8 150 1

Sample Output

190.000000

70.198039

Solution

把下底边看作起点s,上底边看作终点e,s到任一遮阳棚的距离是该遮阳棚的d值,任一遮阳棚到e的距离是l-h-d,任意两个遮阳棚之间的最短距离需要讨论几种情况,我是求出一个点到一个矩形的最短距离,然后对于两个遮阳棚之间的最短距离,只需要求出其中一个遮阳棚的四个顶点到另一个遮阳棚的最短距离取最小值即可,知道这n+2个点之间的距离后跑一遍Floyd即可

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111
int T,n,l,u;
struct node
{
int x1,y1,x2,y2;
node(){};
node(int _x1,int _y1,int _x2,int _y2)
{
x1=_x1,y1=_y1,x2=_x2,y2=_y2;
}
}p[maxn];
double dis[maxn][maxn];
double get_dis(double x1,double y1,double x2,double y2)
{
double x=x2-x1,y=y2-y1;
return sqrt(x*x+y*y);
}
double get(double x,double y,int i)
{
int x1=p[i].x1,y1=p[i].y1,x2=p[i].x2,y2=p[i].y2;
if(x>=x2)
{
if(y>=y2)return get_dis(x,y,x2,y2);
if(y<=y1)return get_dis(x,y,x2,y1);
return x-x2;
}
if(x<=x1)
{
if(y>=y2)return get_dis(x,y,x1,y2);
if(y<=y1)return get_dis(x,y,x1,y1);
return x1-x;
}
if(y>=y2)return y-y2;
return y1-y;
}
int main()
{
freopen("street.in","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&l,&u);
for(int i=1;i<=n;i++)
{
int h,w,d,k;
scanf("%d%d%d%d",&h,&w,&d,&k);
if(k)p[i]=node(u-w,d,u,h+d);
else p[i]=node(0,d,w,h+d);
}
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)
dis[i][j]=1e12;
for(int i=1;i<=n;i++)dis[0][i]=p[i].y1,dis[i][n+1]=l-p[i].y2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int x1=p[i].x1,y1=p[i].y1,x2=p[i].x2,y2=p[i].y2;
double temp=get(x1,y1,j);
temp=min(temp,get(x1,y2,j));
temp=min(temp,get(x2,y1,j));
temp=min(temp,get(x2,y2,j));
dis[i][j]=temp;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[j][i]);
for(int k=0;k<=n+1;k++)
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
printf("%.6f\n",dis[0][n+1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: