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;
}
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;
}
相关文章推荐
- 2016多校训练Contest5: 1001 ATM Mechine hdu5781
- 2016多校训练Contest5: 1012 World is Exploding hdu5792
- 2016多校训练Contest5: 1003 Divide the Sequence hdu5783
- 2016多校训练Contest5: 1011 Two hdu5791
- 2016第三场多校联盟训练1010
- 2016多校联合训练contest4 1012Bubble Sort
- 2016多校训练Contest4: 1012 Bubble Sort hdu5775
- 2016多校训练Contest6: 1002 A Simple Chess hdu5794
- HDOJ 5783 (2016多校联合训练 Training Contest 5) Divide the Sequence
- [HDU5799] This world need more Zhu [2016 Multi-University Training Contest 6(2016多校联合训练2) 1007]
- 2016多校训练Contest7: 1008 Hearthstone hdu5816
- 2016多校训练Contest8: 1003 color II hdu5823
- 2016多校训练Contest9: 1012 Less Time, More profit hdu5855
- 2016多校训练Contest10: 1011 Water problem hdu5867
- 2016多校联合训练4 F - Substring 后缀数组
- HDU 5858 Hard problem (2016 多校训练#10 1002)
- 2016 暑假多校训练 第三场 1007 Explorer Bo HDU 5758
- 2016 Multi-University Training Contest 8(2016多校训练第八场)1011
- 2016多校训练Contest9: 1002 Best Division hdu5845
- 2016多校训练Contest10: 1001 Median hdu5857