Star Way To Heaven(LOJ 6322)

题目

礼国庆 2017 Day6」Star Way To Heaven

内存限制:256 MiB时间限制:1000 ms标准输入输出

题目类型:传统评测方式:文本比较

上传者: 匿名

提交提交记录统计测试数据讨论

1

题目描述

小  伤心的走上了 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;
}

如果路径不行考虑其它方法

对于这种题要考虑性质,可以用笔算

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章