ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CSU-2110 Keeping Cool

2019-02-13 23:41:57  阅读:568  来源: 互联网

标签:Keeping double hot 2110 sand 遮阳伞 CSU 100 Kevin


题目链接

http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2110

题目

Description

Kevin has just gotten back to his car after a morning at the beach and is about to drive away when he realises that he has left his ball somewhere. Thankfully, he remembers exactly where it is! Unfortunately for Kevin, it is extremely hot outside and any sand that is exposed to direct sunlight is very hot. Kevin’s pain tolerance allows him to only run for at most k seconds in the hot sand at one time. Kevin runs at exactly 1 metre per second on hot sand. Scattered around the beach are umbrellas. Each umbrella is a perfect circle and keeps the sand underneath it cool. Each time Kevin reaches an umbrella, he will wait there until his feet cool down enough to run for another k seconds on the hot sand. Note that Kevin will not run more than k seconds in the hot sand at one time, so if two umbrellas are more than k metres apart, Kevin will not run between them. Determine the minimum amount of time that Kevin must be in the sun in order to retrieve his ball and return back to the car.

Input

The first line of input contains four integers n (0 ≤ n ≤ 100), which is the number of umbrellas, k (1 ≤ k ≤ 100), which is the number of metres that Kevin can run on the hot sand, x (−100 ≤ x ≤ 100) and y (−100 ≤ y ≤ 100), which are the coordinates of the beach ball. Kevin starts at his car at (0; 0). You may treat Kevin and the ball as single points. The next n lines describe the umbrellas. Each of these lines contains three integers x (−100 ≤ x ≤ 100), y (−100 ≤ y ≤ 100) and r (1 ≤ r ≤ 100). The umbrella is a circle centred at (x; y) with radius r. There may be multiple items (ball, umbrella(s) or Kevin) at a single location. All measurements are in metres.

Output

Display the minimum amount of time (in seconds) that Kevin must be in the sun. If it is impossible for Kevin to get to the ball and return back to the car, display -1 instead. Your answer should have an absolute or relative error of less than 10−6.

Sample Input

0 1 0 0

0 20 1 2

0 10 20 20

2 2 7 4
6 2 2
2 2 1

1 2 3 3
0 3 2

Sample Output

0.0000000000

4.4721359550

-1

6.1289902045

4.0000000000

题意

给定n,k,x,y,n代表遮阳伞的数量,k代表kevin一次在阳光下可以呆的最长时间,在遮阳伞里呆过后就可以重置,kevin从(0,0)出发,要到(x,y)去,然后再回到(0,0),每秒kevin走1单位长度。下面n行每行给定x, y, r代表遮阳伞的坐标和半径,问kevin能否到达遮阳伞并回来,如不能则输出-1,可以则输出在阳光下呆的最小时间

题解

首先我们先跑一边dijkstra得到起点到每一个遮阳伞之间的最小距离(即在阳光下呆的最小时间和),然后我们判断在能到达的遮阳伞中有没有包含着终点的遮阳伞,有的话就可以转换为能否到这个遮阳伞,什么时候时间最小。如果没有也可以认为是坐标为(x,y) r = 0的遮阳伞。

然后我们再o(n)扫一遍看卡有没有能到这个遮阳伞的伞,有的话就把他们都记录在一个can结构体数组中,结构体记录:1.在阳光下走到终点”遮阳伞“的总时间。 2.这次到这个遮阳伞在阳光中暴露的时间。每次++cnt。之后两层循环枚举所有能到这个伞的组合,看看两次加起来在阳光中暴露的时间是否大于k,若不大于则更新答案,最后输出答案即可。

AC代码

#include<bits/stdc++.h>
#define maxn 150
#define pi pair<double, int>
using namespace std;
double d[maxn];
int n;
double k, x, y;
bool vis[maxn];
double dis(double x1, double y1, double x2, double y2) {
    return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
struct node {
    double x, y, r;
} a[maxn];
struct can {
    double c, d;
} can[maxn];
void dijkstra() {
    priority_queue<pi, vector<pi>, greater<pi> > q;
    fill(d + 1, d + n + 1, 0x7fffffff);
    d[0] = 0.0;
    fill(vis, vis + n + 1, false);
    q.push(make_pair(d[0], 0));
    while (!q.empty()) {
        pi now = q.top(); q.pop();
        int x = now.second;
        if (vis[x]) continue;
        vis[x] = true;
        for (int i = 1; i <= n; i++) {
            int v = i;
            double dd = max(dis(a[x].x, a[x].y, a[i].x, a[i].y) - a[i].r - a[x].r, 0.0);
            if (x != i && dd <= k) {
                if (d[i] > d[x] + dd) {
                    d[i] = d[x] + dd;
                    q.push(make_pair(d[i], i));
                }
            }
        }
    }
}
int main() {
    while (scanf("%d%lf%lf%lf", &n, &k, &x, &y) != EOF) {
        for (int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].r);
        }
        a[0].x = a[0].y = a[0].r = 0;
        dijkstra();
        double min1 = 0x7fffffff;
        int point = n + 1;
        a[point].x = x; a[point].y = y; a[point].r = 0;
        for (int i = 0; i <= n; i++) {
            if (dis(a[i].x, a[i].y, x, y) - a[i].r <= 0 && d[i] < min1) {
                point = i;
                min1 = d[i];
            }
        }
        double ans = 0x7fffffff;
        int cnt = 0;
        for (int i = 0; i <= n; i++) {
            double dd = max(dis(a[i].x, a[i].y, a[point].x, a[point].y) - a[i].r - a[point].r, 0.0);
            if (dd <= k) {
                can[++cnt].c = dd;
                can[cnt].d = d[i] + dd;
            }
        }
        for (int i = 1; i <= cnt; i++) {
            for (int j = 1; j <= cnt; j++) {
                if (can[i].c + can[j].c <= k) {
                    ans = min(ans, can[i].d + can[j].d);
                }
            }
        }
        if (ans != 0x7fffffff) printf("%.10lf\n", ans);
        else printf("-1\n");
    }
    return 0;
}
/**********************************************************************
    Problem: 2110
    User: Artoriax
    Language: C++
    Result: AC
    Time:4 ms
    Memory:2044 kb
**********************************************************************/

标签:Keeping,double,hot,2110,sand,遮阳伞,CSU,100,Kevin
来源: https://www.cnblogs.com/artoriax/p/10372384.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有