[计算几何]JZOJ 3129 数三角形 分析
我们先考虑把每个点向原点连一条直线,那么要构成一个经过原点的三角形都不可能在这条直线的同侧
那么我们把个点按极角排序,然后只统计直线的半边的非黄金三角形个数,就能不重复不遗漏了
答案等于总三角形个数减非黄金三角形个数
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=1e5+10; struct Point { ll x,y; double a; friend bool operator < (Point a,Point b) { return a.a<b.a; } }a[N]; int n; ll ans; ll Multi(int i,int j) { return a[i].x*a[j].y-a[i].y*a[j].x; } void Calc() { int tot=0,now=1; for (int i=1;i<=n;i++) { while (now%n+1!=i&&Multi(i,now%n+1)>=1ll) now++,tot++; ans-=1ll*tot*(tot-1ll)/2ll; tot--; } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y),a[i].a=atan2(a[i].y,a[i].x); sort(a+1,a+n+1); ans=1ll*n*(n-1ll)*(n-2ll)/6; Calc(); printf("%lld",ans); }