HDU 3629-Convex找凸四边形个数(扫描+二分/two pointers)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11713

题意:给n个点,无三点共线,求凸四边形个数。

对应凸四边形,有着一个 凹四边形,其实凹四边形,就相当于一个三角形,内部包含了一个点,则这样就可以构成一个凹四边形。  内部包含x个点,则x个凹四边形。

则题目转化为求有多少个凹四边形,再转为  每个三角形内部有多少个点

就和这题一样了

http://blog.csdn.net/viphong/article/details/51095501


按极角序扫描得到 每个三角形内部多少个点,然后 c(n,4)-它便是答案了


注意加了eps=1e6反而wa,,不加或eps=1e-12都能过。。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=1e-12; 
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;} 
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}

struct node
{
	int x,y;
	node(){}
	double jijiao;
	node(int a,int b){x=a,y=b;}
};
node tm[1255];
node tmp[2455];
bool cmp(node a,node b)
{
	return a.jijiao<b.jijiao;
}
int n;
__int64 count(__int64 x)
{
	int i;
	int idx=1;
	for (i=1;i<=n;i++)
	{
		if (i==x)continue; 
		tmp[idx].x=tm[i].x-tm[x].x;
		tmp[idx].y=tm[i].y-tm[x].y;
		tmp[idx].jijiao=atan2(tmp[idx].y,tmp[idx].x);
		tmp[idx+n-1].jijiao=tmp[idx].jijiao+2*pi;
		idx++;
	}  
	sort(tmp+1,tmp+1+(2*n-2),cmp);
	node tp;
	__int64 res=0;
	for (i=1;i<n;i++)
	{
		tp.jijiao=tmp[i].jijiao+pi+eps;
		int it=upper_bound(tmp+1,tmp+1+2*n-2,tp,cmp)-tmp;
		int cnt=it-i-1;
		res+= cnt*(cnt-1)/2;
	}
	int s= (n-1);
	s*=(n-2)*(n-3);
	s/=6;
	return s-res;
}

int main()
{
	__int64 cnt=1;
	__int64 i;
	int t;cin>>t;
	while(t--)
	{
scanf("%d",&n);
	for (i=1;i<=n;i++)
		scanf("%d%d",&tm[i].x,&tm[i].y);

	__int64 ans=0;
	for (i=1;i<=n;i++) 
		ans+=count(i);
	__int64 tmp=n;
	 tmp*=n-1;
	 tmp*=n-2;
	 tmp*=n-3;
	 tmp/=24;
	 ans=tmp-ans;
	printf("%I64d\n",ans); 
	
	} 
	
	return 0;
	
}


你可能感兴趣的:(HDU 3629-Convex找凸四边形个数(扫描+二分/two pointers))