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

luogu P2992 [USACO10OPEN]三角形计数Triangle Counting

时间:2018-07-08 15:38:01      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:print   ref   因此   std   枚举   有一个   using   pen   int   

https://www.luogu.org/problemnew/solution/P2992

考虑包含原点,不包含原点的三角形有什么特征.

包含原点的三角形:任意找一个顶点和原点连线,一定能把另外两个顶点隔开到两侧.
不包含原点的:三个顶点中只有一个顶点满足:和原点连线后,能把另外两个顶点隔开到两侧.

因此我们统计这样的三点组(x,y,z)的数目:x和原点的连线能把y和z隔开在两侧.
一共C(n,3)个三角形,包含原点的贡献3个三点组,不包含的只贡献1个.
统计三点组的数目只需要把所有点按照极角进行排序,然后枚举x.

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct point{
  int x,y;  
  void read(){
    scanf("%d%d",&x,&y);
  }
  bool operator <(const point &B)const{
    return atan2(y,x)<atan2(B.y,B.x);
  }
}P[200005];
long long cross(point A,point B){
  return A.x*1ll*B.y-A.y*1ll*B.x;
}
int main(){
  int n;scanf("%d",&n);
  for(int i=1;i<=n;++i)P[i].read();
  sort(P+1,P+n+1);
  for(int i=1;i<=n;++i){
    P[n+i]=P[i];
  }
  int j=1;
  long long cnt=0;
  for(int i=1;i<=n;++i){
    while(cross(P[i],P[j+1])>0)++j;
    cnt=cnt+(j-i)*1ll*(n-1-(j-i));
  }
  printf("%lld\n",(cnt-n*1ll*(n-1)*(n-2)/6)/2);
  return 0;
}

luogu P2992 [USACO10OPEN]三角形计数Triangle Counting

标签:print   ref   因此   std   枚举   有一个   using   pen   int   

原文地址:https://www.cnblogs.com/liu-runda/p/9280021.html

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