zoukankan      html  css  js  c++  java
  • hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形

    How Many Triangles

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5784

    Description

    Alice has n points in two-dimensional plane. She wants to know how many different acute triangles they can form. Two triangles are considered different if they differ in at least one point.

    Input

    The input contains multiple test cases.
    For each test case, begin with an integer n,
    next n lines each contains two integers xi and yi.
    3≤n≤2000
    0≤xi,yi≤1e9
    Any two points will not coincide.

    Output

    For each test case output a line contains an integer.

    Sample Input

    3
    1 1
    2 2
    2 3
    3
    1 1
    2 3
    3 2
    4
    1 1
    3 1
    4 1
    2 3

    Sample Output

    0
    1
    2

    Hint

    题意

    平面给你2000个不重合的点,问你有多少个锐角三角形

    题解:

    数一数锐角的数量A和直角+钝角的数量B,那么答案就是(A-2B)/3。 暴力算的话是(O(n^3))的。使用极角排序+two pointers就可以做到(O(n^2log n))
    这边钝角指代范围在90度到180度之间的角(不包括90和180)。

    我们枚举一个点,算出所有向量,然后枚举一个向量,towpointer很容易算出直角那条线,和钝角那条线,然后就可以统计个数了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 2005;
    const int Q = 1e9 + 7;
    
    struct Point {
        int x , y;
        Point (int _x = 0 , int _y = 0) {
            x = _x , y = _y;
        }
        Point operator - (const Point &R) const {
            return Point(x - R.x , y - R.y);
        }
        LL operator ^ (const Point &R) const {
            return (LL)x * R.y - (LL)y * R.x;
        }
        LL operator % (const Point &R) const {
            return (LL)x * R.x + (LL)y * R.y;
        }
        bool sign() const {
            return y > 0 || (y == 0 && x > 0);
        }
        bool operator < (const Point &R) const {
            if (sign() != R.sign()) {
                return sign() > R.sign();
            }
            return (*this ^ R) > 0;
        }
    };
    int n;
    Point P[N];
    
    void work() {
        for (int i = 0 ; i < n ; ++ i) {
            scanf("%d%d" , &P[i].x , &P[i].y);
        }
        LL res = 0;
        for (int i = 0 ; i < n ; ++ i) {
            vector<Point> V;
            for (int j = 0 ; j < n ; ++ j) {
                if (P[j].x != P[i].x || P[j].y != P[i].y)
                    V.push_back(P[j] - P[i]);
            }
    
            sort(V.begin() , V.end());
            int m = V.size();
            int e = 0 , p = 0 , w = 0;
            for (int j = 0 ; j < m ; ++ j) {
                while (e < m && (V[j] ^ V[(j + e) % m]) == 0) {
                    ++ e;
                }
                p = max(e , p);
                while (p < m && ((V[j] ^ V[(j + p) % m]) > 0 && (V[j] % V[(j + p) % m]) > 0)) {
                    ++ p;
                }
                w = max(w , p);
                while (w < m && ((V[j] ^ V[(j + w) % m]) > 0 && (V[j] % V[(j + w) % m]) <= 0)) {
    
                    ++ w;
                }
                res += p - e;
                res -= 2 * (w - p);
                e = max(1 , e - 1);
                p = max(1 , p - 1);
                w = max(1 , w - 1);
            }
        }
        cout << res / 3 << endl;
    }
    
    int main() {
        while (~scanf("%d" , &n)) {
            work();
        }
        return 0;
    }
  • 相关阅读:
    CF1343E-Weights Distributing (最短路)
    科大讯飞杯-日期小助手(补)
    网络15软工个人作业5——软件工程总结
    软工网络15个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3——案例分析
    软工网络15结对编程练习
    软工网络15个人阅读作业2——提问题
    软件工程网络15个人阅读作业1(201521123052 蓝锦明)
    Java课程设计 购物车系统(个人博客) 201521123052 蓝锦明
    201521123052 《Java程序设计》 第14周学习总结
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5731585.html
Copyright © 2011-2022 走看看