链接:https://www.nowcoder.com/acm/contest/201/L
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
Special Judge, 64bit IO Format: %lld
题目描述
Eagle Jump公司正在开发一款新的游戏。Hifumi Takimoto作为其中的员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0, L2:Ax+By+C2=0,还有 n 个圆 。角色在直线上、圆上、园内行走不消耗体力。在其他位置上由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 即算正确。
输入
2 0 1 0 -4
0 1 1
1 3 1
输出
0.236068
解题思路
首先算出两条直线和n个圆相互之间的距离:圆与圆:圆心距离减去两个半径的距离;圆与线:圆心到直线的距离减去半径;线与线:就是两条平行线的距离,若之间的距离小于0,应定为0(距离不为负)。最后跑一边最短路就行了。
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
double inf = 99999999;
int t, vis[1010];
double map[1010][1010], dis[1010];
struct node {
int x, y, r;
}lep[1010];
void Dijkstra(int s)
{
int i, j, k, data;
double min;
for (i = 0; i < t; i++)
{
dis[i] = inf;
vis[i] = 0;
}
dis[s] = 0;
for (i = 0; i < t; i++)
{
min = inf;
for (j = 0; j < t; j++)
{
if (!vis[j] && dis[j] < min)
{
min = dis[j];
data = j;
}
}
vis[data] = 1;
for (k = 0; k < t; k++)
{
if (map[data][k] < inf)
{
if (!vis[k] && dis[k] > dis[data] + map[data][k])
dis[k] = dis[data] + map[data][k];
}
}
}
}
int main()
{
int n, A, B, C1, C2;
while (cin >> n >> A >> B >> C1 >> C2)
{
for (int i = 1; i <= n; i++)
{
cin >> lep[i].x >> lep[i].y >> lep[i].r;
for (int j = 1; j < i; j++)
{
map[i][j] = map[j][i] = sqrt((lep[i].x - lep[j].x) * (lep[i].x - lep[j].x) + (lep[i].y - lep[j].y) * (lep[i].y - lep[j].y)) - lep[i].r - lep[j].r;
if (map[i][j] < 0)
map[i][j] = map[j][i] = 0;
}
}
for (int i = 1; i <= n; i++)
{
map[0][i] = map[i][0] = fabs(A * lep[i].x + B * lep[i].y + C1) / sqrt(A * A + B * B) - lep[i].r;
if (map[0][i] < 0)
map[0][i] = map[i][0] = 0;
}
for (int i = 1; i <= n; i++)
{
map[n + 1][i] = map[i][n + 1] = fabs(A * lep[i].x + B * lep[i].y + C2) / sqrt(A * A + B * B) - lep[i].r;
if (map[n + 1][i] < 0)
map[n + 1][i] = map[i][n + 1] = 0;
}
map[0][n + 1] = map[n + 1][0] = fabs(C1 - C2) / sqrt(A * A + B * B);
t = n + 2;
Dijkstra(0);
cout << dis[n + 1] << endl;
}
return 0;
}