Description
在一只大灰狼偷偷潜入Farmer Don的牛群被群牛发现后,贝西现在不得不履行着她站岗的职责。从她的守卫塔向下瞭望简直就是一件烦透了的事情。她决定做一些开发智力的小练习,防止她睡着了。想象牧场是一个X,Y平面的网格。她将N只奶牛标记为1…N (1 <= N <= 100,000),每只奶牛的坐标为X_i,Y_i (-100,000 <= X_i <= 100,000;-100,000 <= Y_i <= 100,000; 1 <= i <=N)。然后她脑海里想象着所有可能由奶牛构成的三角形。如果一个三角形完全包含了原点(0,0),那么她称这个三角形为“黄金三角形”。原点不会落在任何一对奶牛的连线上。另外,不会有奶牛在原点。给出奶牛的坐标,计算出有多少个“黄金三角形”。顺便解释一下样例,考虑五只牛,坐标分别为(-5,0),
(0,2), (11,2), (-11,-6), (11,-5)。下图是由贝西视角所绘出的图示。 

Input
第一行:一个整数: N 第2到第N+1行: 每行两个整数X_i,Y_i,表示每只牛的坐标
Output
* 第一行: 一行包括一个整数,表示“黄金三角形的数量”
Sample Input
5
-5 0
0 2
11 2
-11 -6
11 -5
-5 0
0 2
11 2
-11 -6
11 -5
Sample Output
5
题解
计算几何,正难则反的思想。答案就是所有三角形去掉非黄金三角形。先极角排序,对于某个点x,其与原点连线所在直线将平面划分为两部分,若一个部分有t个点,在这t个中任取2个与x显然不构成黄金三角形,,画图可知对于每个点只统计某个方向的半平面内的点就能不重不漏。具体可以用一个指针旋转半平面。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
#define pi acos(-1.0)
using namespace std;
int n;
struct dian{int x,y;double dgr;} d[100005];
ll tot,del;
bool operator < (dian i,dian j)
{return i.dgr<j.dgr;}
ll operator * (dian i,dian j)
{return (ll)i.x*j.y-(ll)i.y*j.x;}
void init()
{
scanf("%d",&n);
int i;
for(i=1;i<=n;i++)
{scanf("%d%d",&d[i].x,&d[i].y);
d[i].dgr=atan2(d[i].y,d[i].x);
}
sort(d+1,d+n+1);
tot=(ll)n*(n-2)*(n-1)/6;
}
void work()
{
int i,w=1,ct=0;
for(i=1;i<=n;i++)
{while(w%n+1!=i&&d[i]*d[w%n+1]>=0)
{w=w%n+1;ct++;}
del+=(ll)ct*(ct-1)/2;
ct--;
}
printf("%lld\n",tot-del);
}
int main()
{
init(); work();
return 0;
}