HDU - 3629 Convex(计算凸四边形个数)

题目链接:点击查看

题目大意:给出n个点,计算能组成的凸四边形个数

题目分析:朴素方法是枚举四个点,n^4的复杂度,而这个题目的n给到了700,显然是不行的,既然点的个数比较大,正难则反,我们考虑组合数学,首先n个点能组成C(n,4)个四边形,我们只要减去凹四边形的个数就是答案了,我们记凹四边形的个数为ans,凹四边形,换一种说法,就是取三个点组成的三角形,问有多少个点落在三角形内,那么三角形三个顶点加上落在三角形内部的点,这四个点可以组成凹四边形,具体的计算方法非常巧妙,用到了双指针保证了时间复杂度在O(n)内找到所有的凹四边形,我们在外层先O(n)枚举哪个点作为凹四边形的中心点,也就是极坐标的相对原点,对于其余的n-1个点进行极角排序,排好序后就可以用双指针确定区间了,找到一段最长的区间能够满足其中的所有点构成的三角形都是凸三角形,注意这里是凸三角形,我们记凸三角形的个数为ans2,统计好所有的凸三角形后,凹三角形的个数就是C(n-1,3)-ans2了,同样也是利用组合数学正难则反的求,这样我们就能得到所需要的一切信息了,直接实现就行了,时间复杂度n*n*logn

代码:

#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e3+100;const double eps = 1e-8;const double pi = acos(-1.0);int pos;int sgn(double x){if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}struct Point{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}void input(){scanf("%lf%lf",&x,&y);}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}double distance(Point p){return hypot(x-p.x,y-p.y);}
}point[N];LL C(LL n,LL m)
{if(m>n)return 0;if(m==1)return n;if(m==2)return n*(n-1)/2;if(m==3)return n*(n-1)*(n-2)/6;if(m==4)return n*(n-1)*(n-2)*(n-3)/24;
}double xmult(Point p0,Point p1,Point p2)
{return (p1-p0)^(p2-p0);
}bool cmp(Point a,Point b)
{double temp=xmult(point[pos],a,b);if(sgn(temp)==0)return a.distance(point[pos])0;
}int main()
{
//    freopen("input.txt","r",stdin);
//    ios::sync_with_stdio(false);int w;cin>>w;while(w--){int n;scanf("%d",&n);for(int i=1;i<=n;i++)point[i].input();LL ans=0;for(int i=1;i<=n;i++){vectornode;for(int j=1;j<=n;j++)if(j!=i)node.push_back(point[j]);pos=i;sort(node.begin(),node.end(),cmp);int k=1;LL ans2=0;for(int j=0;j0)//注意这里,k需要转圈走的,所以要对n-1取模k++;ans2+=C(k-j-1,2);}ans+=C(n-1,3)-ans2;}printf("%lld\n",C(n,4)-ans);}return 0;
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部