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

来源:互联网 发布:重庆行知小小学校招聘 编辑:程序博客网 时间:2024/05/22 10:55

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.
3n2000
0xi,yi1e9
Any two points will not coincide.
 

Output
For each test case output a line contains an integer.
 

Sample Input
31 12 22 331 12 33 241 13 14 12 3
 

Sample Output
012

计算几何题目。我们枚举每个点作为角的顶点,然后计算以这个角为顶点的角有多少锐角和钝角【不包括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 5000typedef struct{     long long x;     long long y;}point;point points[N],px[N]; //点集//计算两点之间距离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;}


0 0
原创粉丝点击