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)

  • 相关阅读:
    ROS_Kinetic_08 ROS的集成开发环境(IDEs)之使用Eclipse
    如何写好一份竞品运营分析报告?
    我眼中的Linux设备树(六 memory&chosen节点)
    【干货】前端开发者最常用的六款IDE
    【前端图表】echarts散点图鼠标划过散点显示信息
    【前端图表】echarts实现散点图x轴时间轴
    三分钟教你学会如何将密文解码成明文
    2018上半年GitHub上最热门的开源项目
    进阶攻略|前端完整的学习路线
    进阶攻略|前端最全的框架总结
  • 原文地址:https://www.cnblogs.com/moonbay/p/2155595.html
Copyright © 2011-2022 走看看