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
一个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; }
相关文章推荐
- 【最短路】【Heap-dijkstra】Gym - 101147B - Street
- GYM 101147 A.The game of Osho(博弈论)
- GYM 101147 C.The Wall(二分匹配-hungary)
- Gym 101572 I.Import Spaghetti【Floyd最小环+输出路径】
- 【博弈论】【SG函数】【找规律】Gym - 101147A - The game of Osho
- GYM 101147 D.Popcorn(水~)
- On the way to the park Gym - 101147I 几何
- GYM 101147 E.Jumping(SPFA)
- GYM 100827 L.Wormhole(Floyd)
- 【动态规划】Gym - 101147H - Commandos
- Gym - 101147H H. Commandos DAG
- GYM 100090 C.Graph Restoration(Floyd)
- GYM 101147 F.Bishops Alliance(dp+BIT)
- Gym - 101147E E. Jumping —— bfs
- GYM 101147 G.The Galactic Olympics(dp)
- GYM 101147 H.Commandos(dp)
- GYM 101147 I.On the way to the park(水~)
- Gym - 101147H H. Commandos —— DP
- GYM 101147 J.Whistle's New Car(dfs)
- GYM 101147 K.Touristic Trip(概率DP)