zoukankan      html  css  js  c++  java
  • Codeforces 333E Summer Earnings

    题目传送门

      传送门I

      传送门II

      传送门III

    题目大意

      给定平面上的$n$个点,以三个不同点为圆心画圆,使得圆两两没有公共部分(相切不算),问最大的半径。

      显然答案是三点间任意两点之间的距离的最小值的一半。

      那么一定有一对点的距离会被算入答案。

      考虑将所有边按距离从大到小排序。当加入某一条边的时候出现了三元环。那么这条边的长度的一半就是答案。

      至于判断三元环就用bitset。再加上很难跑满,以及for自带二分之一常数就过了。

      

      标算是二分答案,然后枚举一个点,保留距离和它大于等于$mid$的所有点,求一个凸包然后判断之间最远点对的距离是否大于等于$mid$。

      时间复杂度$O(n^{2}log V)$,常数比较大,可能会比较卡,需要特殊卡常技巧。

      由于答案一定与某一条边的长度有关,所以应该可以二分是哪一条边来减小常数。

    Code

     1 /**
     2  * Codeforces
     3  * Problem#333E
     4  * Accepted
     5  * Time: 2246ms
     6  * Memory: 142056k
     7  */
     8 #include <algorithm>
     9 #include <iostream>
    10 #include <cstdlib>
    11 #include <bitset>
    12 #include <cstdio>
    13 #include <cmath>
    14 #include <ctime>
    15 using namespace std;
    16 typedef bool boolean;
    17 #define ll long long
    18 
    19 typedef class Point {
    20     public:
    21         int x, y;
    22 }Point;
    23 
    24 ll dis2(Point a, Point b) {
    25     return (a.x - b.x) * 1ll * (a.x - b.x) + (a.y - b.y) * 1ll * (a.y - b.y);
    26 }
    27 
    28 typedef class Data {
    29     public:
    30         int x, y;
    31         ll dis;
    32 
    33         boolean operator < (Data b) const {
    34             return dis > b.dis;
    35         }
    36 }Data;
    37 
    38 int n, m;
    39 ll res = 0;
    40 Point* ps;
    41 Data* ds;
    42 bitset<3005> *bs;
    43 
    44 inline void init() {
    45     scanf("%d", &n);
    46     ds = new Data[(n * n + 1)];
    47     ps = new Point[(n + 1)];
    48     bs = new bitset<3005>[(n + 1)];
    49     for (int i = 1; i <= n; i++)
    50         scanf("%d%d", &ps[i].x, &ps[i].y);
    51 }
    52 
    53 inline void solve() {
    54     for (int i = 1; i <= n; i++)
    55         for (int j = i + 1; j <= n; j++)
    56             ++m, ds[m].x = i, ds[m].y = j, ds[m].dis = dis2(ps[i], ps[j]);
    57     sort(ds + 1, ds + m + 1);
    58     for (int i = 1; i <= m; i++) {
    59         int x = ds[i].x, y = ds[i].y;
    60         if ((bs[x] & bs[y]).count()) {
    61             printf("%.9lf", sqrt(ds[i].dis) / 2);
    62             return;
    63         }
    64         bs[x][y] = 1, bs[y][x] = 1;
    65     }
    66     puts("0");
    67 }
    68     
    69 
    70 int main() {
    71     init();
    72     solve();
    73     return 0;
    74 }
  • 相关阅读:
    float
    老师的通病
    无题
    BufferedReader
    剩余定理
    ActionScript 多图加载 按图顺序索引
    C++ Socket 编程
    设计高可用和高负载的网站系统
    提高网站速度的最佳实践【翻译】
    把哈希表存储到数据库中
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9451677.html
Copyright © 2011-2022 走看看