您的位置:首页 > 其它

2016多校训练Contest5: 1004 How Many Triangles hdu5784

2016-08-03 18:15 309 查看
Problem Description

Alice has n points in two-dimensional plane. She wants to know how many different acute triangles they can form. Two triangles are considered different if they differ in at least one point.

 

Input

The input contains multiple test cases.

For each test case, begin with an integer n,

next n lines each contains two integers xi and yi.
3≤n≤2000
0≤xi,yi≤1e9

Any two points will not coincide.

 

Output

For each test case output a line contains an integer.

 

Sample Input

3
1 1
2 2
2 3
3
1 1
2 3
3 2
4
1 1
3 1
4 1
2 3

 

Sample Output

0
1
2

计算几何题目。我们枚举每个点作为角的顶点,然后计算以这个角为顶点的角有多少锐角和钝角【不包括0°和180°】

对于这个点,将其他点极角排序,然后用两个指针扫描,因为排过序了,所以扫描这里是O(n)的

记得扫描的时候多记录几个值来去除0°和180°的角,扫描的时候要判断不能扫过180°

这题我刚写完用官方数据跑了一下是20S

然后改了一个多小时想着先交一发到hdu就直接就A了,而且就跑了2.8S。exm???

这是数据改了还是怎么回事= =我交上去的那份本机跑也还是20多S

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define N 5000
typedef struct
{
long long x;
long long y;
}point;
point points
,px
; //点集
//计算两点之间距离
inline long long dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
//通过矢量叉积求极角关系(p0p1)(p0p2)
//k > 0 ,p0p1在p0p2顺时针方向上
inline long long check(point p1, point p0, point p2)
{
return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
inline long long multi(point p0, point p1, point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
inline bool cmp(point a,point b)
{
if ((a.y-points[0].y)*(b.y-points[0].y)<=0)
{
if ((a.y-points[0].y)==0 && (b.y-points[0].y)==0) return (a.x-points[0].x)<(b.x-points[0].x);
if ((a.y-points[0].y)>0 || (b.y-points[0].y)>0) return (a.y-points[0].y)<(b.y-points[0].y);
}
return (multi(points[0],a,b)>0);

}
long long ans1,ans2;
inline void convex_hull(int n)
{
int i,j,k,d;
double miny=points[0].y;
int index=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
points[j]=px[j];
point temp;
temp=points[i];
points[i]=points[0];
points[0]=temp;
sort(points+1,points+n,cmp); //p[1:n-1]按相对p[0]的极角从小到大排序
for(j=n;j<n*2-1;j++)
points[j]=points[j-n+1];
int k1=1,kk=1,k2=2,k3=2;
while(k1<=n-1)
{
if(kk<=k1)
kk=k1+1;
long long d=multi(points[0],points[k1],points[kk]);
while(d==0&&kk<=n-1&&check(points[k1],points[0],points[k2])>0)
{
kk++;
d=multi(points[0],points[k1],points[kk]);
}
if(k2<kk)
k2=kk;
d=check(points[k1],points[0],points[k2]);
while(d>0&&k2<=n*2-2&&multi(points[k1],points[k2],points[0])>0)
{
k2++;
d=check(points[k1],points[0],points[k2]);
}
ans1+=k2-kk;
if(k3<k2)
k3=k2;
d=check(points[k1],points[0],points[k3]);
while(d<=0&&k3<=n*2-2&&multi(points[k1],points[k3],points[0])>0)
{
k3++;
d=check(points[k1],points[0],points[k3]);
}
ans2+=k3-k2;
k2--;
k1++;
}
}
}
int main()
{
// freopen("1004.in","r",stdin);
// freopen("1004.ans","w",stdout);
int i,j,n;
double sum,area;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=0;i<n;i++)
{
scanf("%I64d%I64d",&points[i].x,&points[i].y);
px[i]=points[i];
}
ans1=0;
ans2=0;
convex_hull(n);
// printf("%I64d %I64d %I64d\n",ans1,ans2,(ans1-(long long)2*ans2)/(long long)3);
printf("%I64d\n",(ans1-(long long)2*ans2)/(long long)3);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算几何