bzoj1914

极角排序

先开始想了很多分割方法,发现都不对,最后觉得只能极角搞搞,就看了答案

我们发现,一个点的原点构成的直线把平面分成了两半,那么只由一边点和这个点构成的三角形肯定不包含原点,那么我们按极角排序,然后计算右边有多少点C(x,2)就行了。因为一个三角形有三个点,枚举到中间那个点的时候这个三角形不会被计算,而如果两边都计算的话就会算重两次,于是我们只计算在右边的三角形就不会重负和遗漏了

极角排序就是计算atan2(y,x),计算出和x轴的弧度夹角,按这个排序就行了

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const double pi = acos(-1);
struct points {
    double x, y, angle;
    points(double x = 0, double y = 0, double angle = 0) : x(x), y(y), angle(angle) {}
    bool friend operator < (points A, points B)
    {
        return A.angle < B.angle;
    }
} a[N];
int n, cnt, pos;
long long ans;
inline long long Sum(long long x)
{
    return x * (x - 1ll) * (x - 2ll) / 6ll;
}
inline long long calc(long long x)
{
    return x * (x - 1ll) / 2ll;
}
inline double A(double x)
{
    return x > 0 ? x : 2 * pi + x;
}
int main()
{
    scanf("%d", &n);
    ans = Sum(n);
    for(int i = 1; i <= n; ++i)
    {
        double x, y, angle;
        scanf("%lf%lf", &x, &y);
        angle = atan2(y, x);
        if(angle < 0) angle += 2 * pi;
        a[i] = points(x, y, angle);
    }
    sort(a + 1, a + n + 1);
    for(int i = 2; i <= n; ++i) if(a[i].angle - a[1].angle > pi)
    {
        pos = i;
        break;
    }
    cnt = pos - 1;
    for(int i = 1; i <= n; ++i)
    {
        --cnt;
        while(A(a[pos].angle - a[i].angle) < pi && pos != i)
        {
            ++pos;
            pos = (pos - 1) % n + 1;
            ++cnt;
        }
        ans -= calc(cnt);
    }
    printf("%lld\n", ans);
    return 0;
}

时间: 2024-08-02 00:20:59

bzoj1914的相关文章

BZOJ1914 [Usaco2010 OPen]Triangle Counting 数三角形

hzwer已经说的很好了,在此只能跪烂了 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42

bzoj1913

这是一道好题,要求每个三点圆覆盖的点数和 我们可以算四边形的贡献,四边形显然分成两种:凸四边形和凹四边形 显然,凹四边形的覆盖只可能是三个点组成三角形包含另一个点,所以贡献是1 凸四边形,其最小圆覆盖是以最长对角线为直径的 注意一个很重要的条件,四点不共圆,所以凸四边形的贡献是2 四边形总数是一定的,显然统计凹四边形更方便 穷举一个点作为原点,即求包含原点的三角形数目——转化为bzoj1914,解决了! 1 uses math; 2 type node=record 3 x,y:longint;

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ