【BZOJ】1914: [Usaco2010 OPen]Triangle Counting 数三角形
2017-10-21 08:17
381 查看
【题意】给定坐标系上n个点,求能构成的包含原点的三角形个数,n<=10^5。
【算法】极角排序
【题解】补集思想,三角形个数为C(n,3)-不含原点三角形。
将所有点极角排序。
对于一个点和原点构成的直线,如果选择这个点和直线一侧的两个点就可以构成不含原点的三角形。
每个点只统计半圈,这样扫1~n下来每个点就会被统计若干次和统计若干次,加起来刚好是答案。这也是基环树DP中的惯用套路。
这样只要用双指针找到半圈内有多少点即可,比较一个点是否在直线一侧可以比较直线向量和目标点向量的叉积是否>0。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll long long using namespace std; const int maxn=100010,eps=1e-8; int n; long long ans; struct point{ ll x,y;double angle; ll operator *(const point a)const{ return x*a.y-a.x*y;// } }a[maxn]; bool cmp(point a,point b){return fabs(a.angle-b.angle)<eps?a.x<b.x:a.angle<b.angle;} int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld%lld",&a[i].x,&a[i].y); a[i].angle=atan2(a[i].y,a[i].x); } sort(a,a+n,cmp); int r=1,num=0;ans=0; for(int i=0;i<n;i++){ while(r!=i&&a[i]*a[r]>=0)r=(r+1)%n,num++; ans+=1ll*num*(num-1)/2; num--; } printf("%lld",1ll*n*(n-1)*(n-2)/6-ans); return 0; }View Code
注意叉积计算后作为int,不是double。
相关文章推荐
- BZOJ 1914: [Usaco2010 OPen]Triangle Counting 数三角形
- [bzoj1914] [Usaco2010 OPen]Triangle Counting 数三角形
- 【bzoj1914】[Usaco2010 OPen]Triangle Counting 数三角形 计算几何
- 【计算几何】【极角序】【二分】bzoj1914 [Usaco2010 OPen]Triangle Counting 数三角形
- BZOJ 1914: [Usaco2010 OPen]Triangle Counting 数三角形
- bzoj1914[Usaco2010 OPen]Triangle Counting 数三角形 极角排序+乱搞
- BZOJ1914 [Usaco2010 OPen]Triangle Counting 数三角形
- [BZOJ1914][Usaco2010 OPen]Triangle Counting 数三角形
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形
- 【bzoj1914】[Usaco2010 OPen]Triangle Counting 数三角形
- BZOJ1914: [Usaco2010 OPen]Triangle Counting 数三角形
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形 容斥
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形【叉积+极角排序+瞎搞】
- 1914: [Usaco2010 OPen]Triangle Counting 数三角形 (计算几何)
- BZOJ 1914 [Usaco2010 OPen]Triangle Counting 数三角形
- BZOJ_1915_[Usaco2010 Open]奶牛的跳格子游戏_DP+单调队列
- BZOJ 1916 [Usaco2010 Open]冲浪
- BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP
- bzoj1916[Usaco2010 Open]冲浪