zoukankan      html  css  js  c++  java
  • hdu 3629 极坐标排序

    /*
    * hdu3629/linux.cpp
    * Created on: 2011-8-25
    * Author : ben
    */
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <cstring>
    #include
    <cmath>
    using namespace std;

    const int MAXN = 705;
    const double PI = acos(-1);

    typedef
    struct {
    int x;
    int y;
    } MyPoint;

    int N;
    MyPoint points[MAXN];
    double angs[MAXN][MAXN];

    int findindex(double *angarray, double ang) {
    int low, mid, high;
    low
    = 0;
    high
    = N - 2;
    while (low <= high) {
    mid
    = (low + high) / 2;
    if (angarray[mid] > ang) {
    high
    = mid - 1;
    }
    else {
    low
    = mid + 1;
    }
    }
    return low;
    }

    void work() {
    int T, i, j, tempindex, center;
    long long tu, ao, num, tempnum;
    double oppang;
    scanf(
    "%d", &T);
    while (T--) {
    scanf(
    "%d", &N);
    for (i = 0; i < N; i++) {
    scanf(
    "%d%d", &points[i].x, &points[i].y);
    }
    tu
    = ((long long) N) * (N - 1) * (N - 2) * (N - 3) / 24;
    for (i = 0; i < N; i++) {
    tempindex
    = 0;
    for (j = 0; j < N; j++) {
    if (j != i) {
    angs[i][tempindex
    ++] = atan2(points[j].y - points[i].y,
    points[j].x
    - points[i].x);
    }
    }
    sort(angs[i], angs[i]
    + N - 1);
    }
    ao
    = ((long long) (N - 1)) * (N - 2) * (N - 3) / 6;
    for (center = 0; center < N; center++) {
    tempnum
    = 0;
    for (i = 0; i < N - 1; i++) {
    if (angs[center][i] > 0) {
    oppang
    = angs[center][i] - PI;
    }
    else {
    oppang
    = angs[center][i] + PI;
    }
    j
    = findindex(angs[center], oppang);
    num
    = (j + N - i - 2) % (N - 1);
    tempnum
    += num * (num - 1) / 2;
    }
    tu
    -= ao - tempnum;
    }
    printf(
    "%I64d\n", tu);
    }
    }

    int main() {
    #ifndef ONLINE_JUDGE
    freopen(
    "data.in", "r", stdin);
    #endif
    work();
    return 0;
    }

      

    这题是去年网络赛的一题,当时不会,王老师想到一个n^3logn的算法,我也没敢打,比赛完后,看解题报告,标程是n^2logn的。前天模拟赛再次遇到这道题,照去年解题报告中方法打了半天,一直是TLE,网上找大牛代码,也就是没有他们写得精练而已。昨天花了一点时间优化,终于不TLE,成WA了。今天下午继续改,最后发现错误竟在于排序用的比较函数写得不对!以后还是用C++吧,C的排序函数真容易出错……

    题目意思是给N个点,问这些点能构成多少个凸四边形。逆向思维,如果四个点不能组成凸四边形,则必然是其中三个点组成一个三角形,另一个点在该三角形内部。
    于是我们可以O(n)枚举一个点作为内部中心,试图从其他的点里选出三个来,组成三角形把它包围住,看看有多少种可能的选择。
    继续观察发现,如果三个点不能圈住中心点,则必然是存在一条通过中心点的直线,使得这三点都在直线的同侧。
    于是我们可以把所有点(除了中心点)按极角排序,然后线性转圈扫描一下就可以统计出来了。总的复杂度是O(n^2*logn)

  • 相关阅读:
    洛谷 1850 NOIP2016提高组 换教室
    2018牛客多校第三场 C.Shuffle Cards
    2018牛客多校第一场 B.Symmetric Matrix
    2018牛客多校第一场 A.Monotonic Matrix
    2018牛客多校第一场 D.Two Graphs
    2018宁夏邀请赛L Continuous Intervals
    2018宁夏邀请赛K Vertex Covers
    BZOJ
    HDU
    ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
  • 原文地址:https://www.cnblogs.com/moonbay/p/2155595.html
Copyright © 2011-2022 走看看