[HDU 5784] How Many Triangles (几何+极角排序)
2016-08-03 10:49
357 查看
HDU - 5784
几何题,给定平面上若干个不重复的点,求这些点能组成多少个锐角三角形
我刚开始的时候想的是枚举钝角和直角
然后计算每三个点能组成的三角形的个数
减去共线的,再减去钝角和直角的个数,即为答案
而且我在极角排序之后,我试图用二分来确定上下界
这样也不是不能做,但是比较麻烦
题解的方法就比较好
统计锐角的个数,设为 A,钝角和直角的个数,设为 B
每个锐角三角形有三个锐角,每个钝角和直角三角形均贡献两个锐角
所以答案即为 A−2B3
然后题解在对每个点极角排序之后,采用 two pointers的方式来找上下界
比二分好写多了,也很方便,时间复杂度 (N2logN)
统计锐角个数的时候,要考虑和当前枚举的点共线的那些点
顺便精度要开得小一些,要开到 1e-10以上
顺便感谢某周教我如何判精度,输出最小角的atan2
比如这题就是 atan2(1,1e9) = 1e-9,然后大两个级别的精度就行
#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <cctype> #include <map> #include <set> #include <queue> #include <bitset> #include <string> using namespace std; typedef pair<int,int> Pii; typedef long long LL; typedef unsigned long long ULL; typedef double DBL; typedef long double LDBL; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define SQR(a) ((a)*(a)) #define PCUT puts("----------") const DBL eps=1e-12, PI=acos(-1.0); const int maxn=2e3+10; int sgn(DBL x){return x>eps?1:(x<-eps?(-1):0);} struct Vector { DBL x,y; Vector operator - (const Vector &v) const {return {x-v.x, y-v.y};} DBL operator * (const Vector &v) const {return x*v.x + y*v.y;} int read() {return scanf("%lf%lf", &x, &y);} }; typedef Vector Point; int N; Point P[maxn]; DBL ang[2*maxn]; int Cnt(DBL); int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif printf("%.12f\n", atan2(1,1e9)); while(~scanf("%d", &N)) { for(int i=0; i<N; i++) P[i].read(); LL ans = 0, nans=0; for(int i=0; i<N; i++) { Vector L; for(int j=i+1; j<i+N; j++) { int id=j%N; L = P[id]-P[i]; ang[j-i-1] = atan2(L.y, L.x); } sort(ang, ang+N-1); memcpy(ang+N-1, ang, sizeof(DBL)*(N-1)); for(int j=N-1; j<2*N-2; j++) ang[j] += 2.0*PI; int res = Cnt(PI*0.5); ans += res; nans += Cnt(PI) - res; } printf("%lld\n", (ans-2*nans)/3); } return 0; } int Cnt(DBL A) { int r=0, res=0; for(int l=0; l<N-1; l++) { int ecnt=0; while( sgn(ang[l+ecnt]-ang[l]) == 0) ecnt++; l = l+ecnt-1; r = max(r, l+1); while( r-l+1 <= N-1 && sgn(ang[r]-ang[l] - A) < 0) r++; res += (r-l-1)*ecnt; } return res; }
相关文章推荐
- hdu-5784 How Many Triangles(计算几何+极角排序)
- hdu 5784 How Many Triangles 极角排序计算锐角直角钝角
- HDU 5784- How Many Triangles-计算几何-two-pointer-数锐角三角形个数
- 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_HowManyTriangles(极角排序&&尺取法)
- HDU 5784 How Many Triangles
- HDU 5784 How Many Triangles
- HDU 3561 How many times 【计算几何】
- 【HDU5784】How Many Triangles(极角排序 + two-pointer)
- hdu 1213 How Many Tables
- hdu 2138 How many prime numbers(求素数)
- hdu 1130 How Many Trees?
- hdu 2157 How many ways??
- soj 3137 Simple Computing 容斥原理 hdu 1796 How many integers can you find