題目
禮國慶 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;
}
如果路徑不行考慮其它方法
對於這種題要考慮性質,可以用筆算