• 2017 Russian Code Cup (RCC 17), Elimination Round D


    D - Acute Triangles

    思路:

    极角排序+点积叉积

    在一个三角形中,如果它是直角或者顿角三角形,那么直角和顿角只会出现一次

    所以直角和顿角三角形的个数等于直角和顿角的个数

    所以锐角三角形的个数等于三元组个数减去直角和顿角的个数

    三点共线看成退化的顿角三角形

    怎么算直角和顿角个数呢, 先按某个点极角排序,然后暴力过取,用双指针维护到

    当前幅角距离为pi/2 到 3*pi/2 的区间, 区间内点的个数就是到当前幅角为直角或顿角的个数

    可以用点积和叉积分别判断角度和相对方向

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-(long double)1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdd pair<long double, long double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
    
    const int N = 2e3 + 5;
    struct point {
        LL x, y;
        point(){}
        point(LL x, LL y):x(x), y(y){}
        LL dot(point p) {
            return x*p.x + y*p.y;
        }
        LL cross(point p) {
            return x*p.y - y*p.x;
        }
    }p[N], t[N];
    bool anglecmp(point a, point b) {
        if(a.y <= 0 && b.y > 0) return true;
        if(a.y > 0 && b.y <= 0) return false;
        if(!a.y && !b.y) return a.x < b.x;
        return a.cross(b) > 0;
    }
    bool acute(point a, point b) {
        return a.dot(b) > 0 && a.cross(b) >= 0;
    }
    bool acute2(point a, point b) {
        return a.dot(b) > 0 && a.cross(b) < 0;
    }
    int main() {
        int T, n;
        scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) scanf("%lld %lld", &p[i].x, &p[i].y);
            LL ans = 1LL*n*(n-1)*(n-2)/6;
            for (int i = 1; i <= n; i++) {
                int cnt = 0;
                for (int j = 1; j <= n; j++) {
                    if(j!=i)
                        t[++cnt] = point(p[j].x - p[i].x, p[j].y - p[i].y);
                }
                sort(t+1, t+1+cnt, anglecmp);
                int l = 1, r = 1;
                for (int j = 1; j <= cnt; j++) {
                    while(l <= cnt && acute(t[j], t[l])) l++;
                    while(r <= cnt && !acute2(t[j], t[r])) r++;
                    ans -= r-l;
                }
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    各种方便有用的文档资源的网站
    微信小程序swiper实现轮播图
    python使用小记录
    机器作曲参考
    panda读取合并表格数据并保存为pkl格式并读取
    深度学习相关的论文的下载地址
    python读取文本文件
    Python listdir获取某个目录下所有文件名
    Numpy 写3层神经网络拟合sinx
    NLP学习参考
  • 原文地址:https://www.cnblogs.com/widsom/p/10108178.html
Copyright © 2020-2023  润新知