Hdu 5784 How Many Triangles(极角排序+尺取法)
2017-09-05 20:07
344 查看
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5784
思路:
1.锐角三角形总锐角个数=总锐角数-非锐角三角形提供锐角数。则锐角三角形个数=总锐角数/3(即(锐角数-2*(直角+钝角数))/3,每钝角和直角三角形提供两锐角)。
2.枚举每个点p[i],以p[i]为原点,求其他n-1个点与原点组成的向量,按极角(小于0时加2*PI)递增排序。设置三个指针l、r、equ,分别代表第一个直角、第一个平角、第一个非0角的位置。枚举n-1个向量j,由于极角递增,两向量角度即为极角l-极角j,l、r、equ递增则形成的角度也递增(相当于尺取法)。则以点p[i]为顶点的锐角个数为l-equ(所有小于90度的角减去0度的角),钝角个数为r-l(所有小于180度的角减去小于等于90度的角)。
3.当指针l、r、equ旋转一周时(l、r、equ下标超过n-1,但此时所有角度尚未枚举完毕),为了便于求角度(即最后一部分向量与起始部分向量所成角度),枚举之前将所有极角加2*PI复制一遍。
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug
using namespace std;
const double eps=1e-11;
const double PI=acos(-1.0);
const int maxn=4000+50;
int n;
struct Point
{
double x,y;
Point() {}
Point(double x,double y):x(x),y(y) {}
void read()
{
scanf("%lf%lf",&x,&y);
}
};
typedef Point Vector;
Vector operator - (Vector A,Vector B)
{
return Vector(A.x-B.x,A.y-B.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
int cnt;
Point p[maxn];
double a[maxn];
int main()
{
#ifdef debu
freopen("in.txt","r",stdin);
#endif // debug
while(scanf("%d",&n)!=EOF)
{
int acute=0,notacute=0;
for(int i=1; i<=n; i++) p[i].read();
for(int i=1; i<=n; i++)
{
cnt=0;
for(int j=1; j<=n; j++)
{
if(i==j)continue;
Vector tmp=p[j]-p[i];
double ang=atan2(tmp.y,tmp.x);
if(ang<0) ang+=2*PI;
a[++cnt]=ang;
}
sort(a+1,a+cnt+1);
for(int j=1;j<=cnt;j++) a[cnt+j]=a[j]+2*PI;
int l=1,r=1,equ=1;
for(int j=1; j<=cnt; j++)
{
while(l<=2*cnt&&dcmp(a[l]-a[j]-PI/2)<0) l++;
while(r<=2*cnt&&dcmp(a[r]-a[j]-PI)<0) r++;
while(equ<=2*cnt&&dcmp(a[equ]-a[j])==0) equ++;
acute+=l-equ;
notacute+=r-l;
}
}
printf("%d\n",(acute-2*notacute)/3);
}
return 0;
}
思路:
1.锐角三角形总锐角个数=总锐角数-非锐角三角形提供锐角数。则锐角三角形个数=总锐角数/3(即(锐角数-2*(直角+钝角数))/3,每钝角和直角三角形提供两锐角)。
2.枚举每个点p[i],以p[i]为原点,求其他n-1个点与原点组成的向量,按极角(小于0时加2*PI)递增排序。设置三个指针l、r、equ,分别代表第一个直角、第一个平角、第一个非0角的位置。枚举n-1个向量j,由于极角递增,两向量角度即为极角l-极角j,l、r、equ递增则形成的角度也递增(相当于尺取法)。则以点p[i]为顶点的锐角个数为l-equ(所有小于90度的角减去0度的角),钝角个数为r-l(所有小于180度的角减去小于等于90度的角)。
3.当指针l、r、equ旋转一周时(l、r、equ下标超过n-1,但此时所有角度尚未枚举完毕),为了便于求角度(即最后一部分向量与起始部分向量所成角度),枚举之前将所有极角加2*PI复制一遍。
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug
using namespace std;
const double eps=1e-11;
const double PI=acos(-1.0);
const int maxn=4000+50;
int n;
struct Point
{
double x,y;
Point() {}
Point(double x,double y):x(x),y(y) {}
void read()
{
scanf("%lf%lf",&x,&y);
}
};
typedef Point Vector;
Vector operator - (Vector A,Vector B)
{
return Vector(A.x-B.x,A.y-B.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
int cnt;
Point p[maxn];
double a[maxn];
int main()
{
#ifdef debu
freopen("in.txt","r",stdin);
#endif // debug
while(scanf("%d",&n)!=EOF)
{
int acute=0,notacute=0;
for(int i=1; i<=n; i++) p[i].read();
for(int i=1; i<=n; i++)
{
cnt=0;
for(int j=1; j<=n; j++)
{
if(i==j)continue;
Vector tmp=p[j]-p[i];
double ang=atan2(tmp.y,tmp.x);
if(ang<0) ang+=2*PI;
a[++cnt]=ang;
}
sort(a+1,a+cnt+1);
for(int j=1;j<=cnt;j++) a[cnt+j]=a[j]+2*PI;
int l=1,r=1,equ=1;
for(int j=1; j<=cnt; j++)
{
while(l<=2*cnt&&dcmp(a[l]-a[j]-PI/2)<0) l++;
while(r<=2*cnt&&dcmp(a[r]-a[j]-PI)<0) r++;
while(equ<=2*cnt&&dcmp(a[equ]-a[j])==0) equ++;
acute+=l-equ;
notacute+=r-l;
}
}
printf("%d\n",(acute-2*notacute)/3);
}
return 0;
}
相关文章推荐
- HDU 5784 How Many Triangles
- HDU 5784 How Many Triangles
- hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形
- HDU_5784_HowManyTriangles(极角排序&&尺取法)
- HDU 5784 How Many Triangles 极角排序
- HDU 5784 How Many Triangles(极角排序)
- HDU 5784 How Many Triangles(计算几何)
- hdu 5784 How Many Triangles 极角排序计算锐角直角钝角
- HDU 5784 How Many Triangles
- HDU 5784 How Many Triangles
- [HDU 5784] How Many Triangles (几何+极角排序)
- HDU 5784- How Many Triangles-计算几何-two-pointer-数锐角三角形个数
- hdu-5784 How Many Triangles(计算几何+极角排序)
- HDU-3038 How Many Answers Are Wrong 带权并查集
- HDU-How Many Tables
- HDU1130_How Many Trees?(卡特兰数 _java)
- 【并查集】HDU 1213 How Many Tables
- HDU 3038 How Many Answers Are Wrong(kuangbin带你飞 专题五:并差集)
- HDU 5137 How Many Maos Does the Guanxi Worth
- HDU 1213 How Many Tables