题目
礼国庆 2017 Day6」Star Way To Heaven
内存限制:256 MiB时间限制:1000 ms标准输入输出
题目类型:传统评测方式:文本比较
上传者: 匿名
题目描述
小 伤心的走上了 Star way to heaven。
到天堂的道路是一个笛卡尔座标系上一个 的长方形通道 顶点在 和 。
小 从最左边任意一点进入,从右边任意一点走到天堂,最左最右的距离为 ,上下边界距离为 。
其中长方形有 个 ,每个 都有一个整点座标, 的大小可以忽略不计。
每个 以及长方形上下两个边缘宇宙的边界都有引力,所以为了成功到达 小 离他们越远越好。
请问小 走到终点的路径上,距离所有星星以及边界的最小距离最大值可以为多少?
输入格式
一行三个整数 。
接下来 行,每行两个整数 表示一个点的座标。
输出格式
一行一个数表示答案。
样例
样例输入
10 5 2
1 1
2 3
样例输出
1.11803399
题解&分析
首先是考虑二分答案t,但是对于这种笛卡尔座标系,如果要找出一条可行的路径是很困难的
所以考虑其他方法判断t是否满足
很难发现,可以对于每一个Star以半径为t画一个圆
如果这些圆有交集,且它们相交在一起把整个m高度都阻挡了
那么这些圆中相交最大的长度就是ans
就可以用Prim求解(完全图),则二分就不用了
因为有精度问题,所以ans少一点点即可,不影响精度
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
#define ll long long
const int MAXN = 6003;
double n , m;
int K;
bool vis[MAXN];
double dis[MAXN] , X[MAXN] , Y[MAXN];
int main()
{
scanf( "%lf%lf%d" , &n , &m , &K );
for( int i = 1 ; i <= K ; i ++ ){
scanf( "%lf%lf" , &X[i] , &Y[i] );
dis[i] = Y[i];
}
dis[K+1] = m;
dis[0] = 0x7f7f7f7f7f;
double ans = 0;
while( 1 ){
int tot = 0;
for( int i = 1 ; i <= K + 1 ; i ++ ){
if( dis[tot] > dis[i] && vis[i] == 0 ){
tot = i;
}
}
vis[tot] = 1;
ans = max( ans , dis[tot] );
dis[tot] = 0;
if( tot == K + 1 ){
printf( "%.9lf\n" , ans / 2.0 );
return 0 ;
}
for( int i = 1 ; i <= K ; i ++ ){
if( dis[tot] + sqrt( ( X[tot] - X[i] ) * ( X[tot] - X[i] ) * 1.0 + ( Y[tot] - Y[i] ) * ( Y[tot] - Y[i] ) * 1.0 ) < dis[i] && vis[i] == 0 )
dis[i] = dis[tot] + sqrt( ( X[tot] - X[i] ) * ( X[tot] - X[i] ) * 1.0 + ( Y[tot] - Y[i] ) * ( Y[tot] - Y[i] ) * 1.0 );
}
dis[K+1] = min( dis[K+1] , m - Y[tot] );
}
return 0;
}
如果路径不行考虑其它方法
对于这种题要考虑性质,可以用笔算