zoukankan      html  css  js  c++  java
  • CSU-2110 Keeping Cool

    题目链接

    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.

    img

    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
    ", ans);
    		else printf("-1
    ");
    	}
    	return 0;
    }
    /**********************************************************************
    	Problem: 2110
    	User: Artoriax
    	Language: C++
    	Result: AC
    	Time:4 ms
    	Memory:2044 kb
    **********************************************************************/
    
    
  • 相关阅读:
    nodejs安装express及ejs模板
    nodejs开启服务器
    php 汉字转拼音
    使PHP像js一样链式写法
    apache出现\xef\xbb\xbf
    更改CI自定义类构造函数的传参方式
    DEV ComBoxEdit实现模糊检索数据
    微软一站式示例代码库(中文版)20110924版本, 新添加ASP.NET, Windows Base, Silverlight, WinForm等20个Sample
    Windows Azure 系列分享一:开始基于Windows Azure的开发与部署所需的概念和软件
    Windows Azure 系列分享二: Worker Role & Web Role
  • 原文地址:https://www.cnblogs.com/artoriax/p/10372384.html
Copyright © 2011-2022 走看看