码迷,mamicode.com
首页 > 其他好文 > 详细

1284E

时间:2020-01-28 00:13:53      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:div   max   col   scan   for   end   names   c++   pre   

计算几何

先枚举被围住的点 计算合法比较困难 考虑计算不合法方案数 

枚举其他点 选一个点连线作为基准边 当其他三个点连线都在基准边的一侧时不合法 极角排序+双指针统计即可

时间复杂度$O(n^{2}logn)$

技术图片
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5005;
int n;
int x[maxn], y[maxn];
struct Vec {
    int x, y;
    Vec() = default;
    Vec(int _x, int _y) : x(_x), y(_y) {}
    ll friend operator ^ (const Vec &a, const Vec &b) {
        return 1LL * a.x * b.y - 1LL * a.y * b.x;
    }
    bool friend operator < (const Vec &a, const Vec &b) {
        if(1LL * a.y * b.y < 0) {
            return a.y > b.y;
        }
        return (a ^ b) > 0;
    }
} st[maxn];
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
         scanf("%d%d", &x[i], &y[i]);
    }
    ll ans = 0;
    for(int i = 1; i <= n; ++i) {
        int top = 0;
        for(int j = 1; j <= n; ++j) {
            if(j != i) {
                st[++top] = Vec(x[j] - x[i], y[j] - y[i]);
            }
        }
        sort(st + 1, st + top + 1);
        for(int j = 1; j < n; ++j) {
            st[++top] = st[j];
        }
        int pos = 1;
        for(int j = 1; j < n; ++j) {
            pos = max(pos, j);
            while(pos + 1 <= top && (st[j] ^ st[pos + 1]) > 0) {
                ++pos;
            }
            ll c = pos - j;
            ans += c * (c - 1) * (c - 2) / 6LL;
        }
    }
    printf("%lld\n", 1LL * n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 24LL - ans);
    return 0;
}
View Code

 

1284E

标签:div   max   col   scan   for   end   names   c++   pre   

原文地址:https://www.cnblogs.com/19992147orz/p/12237177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!