• FJ省队集训DAY1 T1


    题意:有一堆兔子,还有一个r为半径的圆,要求找到最大集合满足这个集合里的兔子两两连边的直线不经过圆。

    思路:发现如果有两个点之间连边不经过圆,那么他们到圆的切线会构成一段区间,那么这两个点的区间一定会有交集,形如s0 s1 e0 e1

    同样的,如果是n个点,那就是s0 s1 s2..sn e0 e1 e2.. en

    因此,我们枚举那个起始点,然后对于其他点我们按照s排序,对于e做最长上升子序列即可。时间复杂度O(n^2 logn)

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cmath>
     4 #include <vector>
     5 const double pi = 3.14159265358979324;
     6 double th1[2000], th2[2000], b[2000], x[2000], y[2000];
     7 std::pair<std::pair<double, double>, int> a[2000];
     8 int t[2001], t2[2001], f[2001], n;
     9 std::vector<int> ansv;
    10 double r;
    11 int main() {
    12     freopen("crazy.in", "r", stdin);
    13     freopen("crazy.out", "w", stdout);
    14     scanf("%d%lf", &n, &r);
    15     for (int i = 0; i < n; i++) {
    16         scanf("%lf%lf", &x[i], &y[i]);
    17         double th = atan2(y[i], x[i]);
    18         double dth = acos(r / sqrt(x[i] * x[i] + y[i] * y[i]));
    19         th1[i] = th + dth; if (th1[i] > pi) th1[i] -= 2*pi;
    20         th2[i] = th - dth; if (th2[i] <= -pi) th2[i] += 2*pi;
    21         if (th1[i] > th2[i]) std::swap(th1[i], th2[i]);
    22     }
    23     int ans = 1;
    24     ansv.push_back(0);
    25     for (int i = 0; i < n; i++) {
    26         int l = 0, ans2 = -1;
    27         for (int j = 0; j < n; j++)
    28             if (i != j && (th1[j] < th1[i] || th1[j] > th2[i] || th2[j] < th1[i] || th2[j] > th2[i])
    29                     && (th1[j] > th1[i] && th1[j] < th2[i] || th2[j] > th1[i] && th2[j] < th2[i])) {
    30                 if (th1[j] > th1[i] && th1[j] < th2[i]) {
    31                     a[l].first.first = th1[j] - th1[i];
    32                     a[l].first.second = th2[j] - th2[i];
    33                 } else {
    34                     a[l].first.first = th2[j] - th1[i];
    35                     a[l].first.second = th1[j] - th2[i];
    36                 }
    37                 if (a[l].first.second < 0) a[l].first.second += 2*pi;
    38                 a[l].second = j;
    39                 l++;
    40             }
    41         std::sort(a, a + l);
    42         for (int j = 0; j < l; j++) b[j] = a[j].first.second;
    43         std::sort(b, b + l);
    44         for (int j = 1; j <= l; j++) t[j] = 0;
    45         for (int j = 0; j < l; j++) {
    46             int p = std::lower_bound(b, b + l, a[j].first.second) - b + 1;
    47             int v = 0, v2 = -1;
    48             for (int k = p; k; k -= k&-k)
    49                 if (t[k] > v) v = t[k], v2 = t2[k];
    50             v++;
    51             f[a[j].second] = v2;
    52             if (v+1 > ans) ans = v+1, ans2 = a[j].second;
    53             for (int k = p; k <= l; k += k&-k)
    54                 if (t[k] < v) t[k] = v, t2[k] = a[j].second;
    55         }
    56         if (ans2 != -1) {
    57             ansv.clear();
    58             while (ans2 != -1)
    59                 ansv.push_back(ans2), ans2 = f[ans2];
    60             ansv.push_back(i);
    61         }
    62     }
    63     printf("%d
    ", ans);
    64     return 0;
    65 }
  • 相关阅读:
    洛谷 P2616 [USACO10JAN]购买饲料II Buying Feed, II
    洛谷 P3654 First Step (ファーストステップ)
    洛谷 P1223 排队接水
    洛谷 【P1252】马拉松接力赛
    codevs 4927 线段树练习5
    洛谷 P1678 烦恼的高考志愿
    初识 线段树
    开学第一测
    洛谷 P1531 I Hate It
    CSS3 过渡
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5639063.html
Copyright © 2020-2023  润新知