HDU 5784 How Many Triangles
2016-08-03 12:31
387 查看
求二维平面上的n个点可以组合成多少个不同锐角三角形,有一个点位置不同即不同。
数一数锐角的数量A和直角+钝角的数量B,那么答案就是(A-2B)/3。
使用极角排序+two pointers就可以做到O(n2log n)。
这边钝角指代范围在90度到180度之间的角(不包括90和180)。
蒟蒻:没把同向的边处理好,结构体里重载运算的地方没改成ll。
极角排序:先按象限划分好,然后判一下逆时针就好了。
对于本题数据,在判是否同向时,先看是否同象限会略快。
极角排序+尺取
数一数锐角的数量A和直角+钝角的数量B,那么答案就是(A-2B)/3。
使用极角排序+two pointers就可以做到O(n2log n)。
这边钝角指代范围在90度到180度之间的角(不包括90和180)。
蒟蒻:没把同向的边处理好,结构体里重载运算的地方没改成ll。
极角排序:先按象限划分好,然后判一下逆时针就好了。
对于本题数据,在判是否同向时,先看是否同象限会略快。
极角排序+尺取
#include<set> #include<ctime> #include<queue> #include<cstdio> #include<bitset> #include<cctype> #include<bitset> #include<cstdlib> #include<cassert> #include<cstring> #include<iostream> #include<algorithm> #define inf (1<<30) #define INF (1ll<<62) #define fi first #define se second #define rep(x,s,t) for(register int x=s,t_=t;x<t_;++x) #define per(x,s,t) for(register int x=t-1,s_=s;x>=s_;--x) #define prt(x) cout<<#x<<":"<<x<<" " #define prtn(x) cout<<#x<<":"<<x<<endl #define pb(x) push_back(x) #define hash asfmaljkg #define rank asfjhgskjf #define y1 asggnja #define y2 slfvm using namespace std; typedef long long ll; typedef pair<int,int> ii; template<class T>void sc(T &x){ int f=1;char c;x=0; while(c=getchar(),c<48)if(c=='-')f=-1; do x=x*10+(c^48); while(c=getchar(),c>47); x*=f; } template<class T>void nt(T x){ if(!x)return; nt(x/10); putchar(x%10+'0'); } template<class T>void pt(T x){ if(x<0)putchar('-'),x=-x; if(!x)putchar('0'); else nt(x); } template<class T>void ptn(T x){ pt(x);putchar('\n'); } template<class T>void pts(T x){ pt(x);putchar(' '); } template<class T>inline void Max(T &x,T y){if(x<y)x=y;} template<class T>inline void Min(T &x,T y){if(x>y)x=y;} const int maxn=2005; int n; int x[maxn],y[maxn]; struct abcd{ ll x,y;int v; abcd(){} abcd(ll x_,ll y_){ //x==0&&y==0? x=x_;y=y_; if(x>0&&y>=0)v=0; else if(x<=0&&y>0)v=1; else if(x<0&&y<=0)v=2; else if(x>=0&&y<0)v=3; } inline ll operator*(const abcd &a)const{ return x*a.x+y*a.y; } inline ll operator^(const abcd &a)const{ return x*a.y-a.x*y; } inline abcd operator+(const abcd &a)const{ return abcd(x+a.x,y+a.y); } inline abcd operator-(const abcd &a)const{ return abcd(x-a.x,y-a.y); } inline bool operator<(const abcd &a)const{ if(v^a.v)return v<a.v; return x*a.y-a.x*y>0; } inline bool operator==(const abcd &a)const{ return v==a.v&&x*a.y==a.x*y; } }d[maxn<<1]; void solve(){ rep(i,0,n)sc(x[i]),sc(y[i]); ll A=0,B=0; rep(i,0,n){ int tot=0; rep(j,0,n)if(i!=j) d[tot++]=abcd(x[j]-x[i],y[j]-y[i]); sort(d,d+tot); rep(j,tot,tot<<1)d[j]=d[j-tot]; int top=1,cnt=0; rep(j,0,tot){ Max(top,j+1); while(top<j+tot){ if((d[j]^d[top])>0) top++; else if(d[j]==d[top]){ cnt++; top++; } else break; } B+=top-j-1-cnt; if(cnt)cnt--; }//0<d<180° top=1,cnt=0; rep(j,0,tot){ Max(top,j+1); while(top<j+tot){ if((d[j]^d[top])>0&&d[top]*d[j]>0) top++; else if(d[j]==d[top]){ cnt++;top++; continue; } else break; } A+=top-j-1-cnt; if(cnt)cnt--; }//0<d<90° } ll ans=(A-(B-A)*2)/3; ptn(ans); } int main(){ // freopen("pro.in","r",stdin); // freopen("chk.out","w",stdout); while(~scanf("%d",&n))solve(); return 0; }
相关文章推荐
- 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 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 2138 How many prime numbers(Miller_Rabin法判断素数 【*模板】 用到了快速幂算法 )
- 【hdu 1213】How Many Tables
- HDU 1978 How many ways 记忆化DP .
- hdu 1796 How many integers can you find(容斥定理)
- HDU 1213 How Many Tables
- HDU 1555 How many days?
- HDU 1978 How many ways