版权声明:转载请标明出处 https://blog.csdn.net/weixin_41190227/article/details/89743186
题目描述
Eagle Jump公司正在开发一款新的游戏。Hifumi Takimoto作为其中的员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0, L2:Ax+By+C2=0,还有 n 个圆 Ci:(x−xi)2+(y−yi)2=ri2Ci:(x−xi)2+(y−yi)2=ri2。角色在直线上、圆上、园内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
Hifumi Takimoto想从 L1 出发,走到 L2 。请计算最少需要多少体力。输入描述:
第一行五个正整数 n,A,B,C1,C2 (1≤ n ≤ 1000, -10000 ≤ A,B,C1,C2 ≤ 10000),其中 A,B 不同时为 0。 接下来 n 行每行三个整数 x,y,r(-10000 ≤ x,y ≤ 10000, 1≤ r ≤ 10000) 表示一个圆心为 (x,y),半径为 r 的圆。输出描述:
仅一行一个实数表示答案。与正确结果的绝对误差或者相对误差不超过 10-4 即算正确。示例1
输入
2 0 1 0 -4 0 1 1 1 3 1输出
0.236068
解题思路: 对两条直线与每个圆去建图,跑Dijkstra就可以了。
/* @Author: Top_Spirit @Language: C++ */ #include <bits/stdc++.h> using namespace std ; const int Maxn = 1e4 + 10 ; const int INF = 0x3f3f3f3f ; int n, A, B, C1, C2; double Map[Maxn][Maxn]; struct node{ double x, y, r; }circle[Maxn]; void init() { for(int i = 0 ; i <= n + 1; i++){ for(int j = 0; j <= n + 1; j++) { if(i == j)Map[i][j] = 0; else Map[i][j] = INF; } } } bool cmp (node p, node q) { if(p.x == q.x)return p.y < p.y; return p.x < p.y; } double dis[Maxn]; bool vis[Maxn]; void Dijkstra() { for (int i = 0; i <= n+1; i++) { dis[i] = Map[0][i]; } vis[0] = 1; for (int i = 0; i < n+1; i++) { double MIN = INF; int x = -1; for (int j = 0; j <= n+1; j++) { if (!vis[j] && dis[j]<MIN) { MIN = dis[j]; x = j; } } vis[x] = 1; for (int j = 0; j <= n+1; j++) { if (!vis[j] && MIN + Map[x][j]<dis[j]) { dis[j] = Map[x][j] + MIN; } } } } int main() { while(cin >> n >> A >> B >> C1 >> C2) { for(int i = 1; i <= n; i++) { cin >> circle[i].x >> circle[i].y >> circle[i].r; } init(); Map[0][n+1] = Map[n+1][0] = abs(C1-C2)/sqrt(A*A+B*B); for(int i = 1; i <= n; i++) { double k = abs(A*circle[i].x + B*circle[i].y + C1)/sqrt(A*A+B*B) - circle[i].r; if(k < 0)k = 0; Map[0][i] = Map[i][0] = k; } for(int i = 1; i <= n; i++) { double k = abs(A*circle[i].x + B*circle[i].y + C2)/sqrt(A*A+B*B) - circle[i].r; if(k < 0)k = 0; Map[i][n+1] = Map[n+1][i] = k; } for(int i = 1 ; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i != j){ double k = sqrt(abs(circle[i].x - circle[j].x) * abs(circle[i].x - circle[j].x) + abs(circle[i].y - circle[j].y) * abs(circle[i].y - circle[j].y)) - circle[i].r - circle[j].r; if(k < 0)k = 0; Map[i][j] = k; } } } memset(vis, 0, sizeof(vis)); Dijkstra(); printf("%lf\n", dis[n+1]); } return 0; }