• 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)

  • 相关阅读:
    把Outlook与Google Calendar同步了
    (int) Int32.Parse() Convert.toInt32() (转)
    Http Context(转)
    DataReader DataSet(转)
    主键和外键(转)
    显卡参数学习
    开源抽象工厂模式,序列化,反序列化等..
    ASP.NET中App_Code,App_Data等文件夹的作用(转)
    using tianjiayinyong qubie
    xuliehua fanxuliehua xml(zhuan)
  • 原文地址:https://www.cnblogs.com/moonbay/p/2155595.html
Copyright © 2020-2023  润新知