【bzoj1132】[POI2008]Tro 计算几何

按照横坐标为第一关键字,纵坐标为第二关键字排序,
枚举每个点作为原点
把再它后面的点拿出来,求每一对点与原点构成的三角形的面积
abs(a[i].x*a[j].y-a[i].y*a[j].x)
如果能去掉绝对值,就可以用乘法分配律来做了
考虑按极角排序
从下向上枚举每一个点,那么当前点与每一个前面的点的叉积小于0,与后面的点叉积大于0
那么我们边枚举边,记录一个前缀和,每次ans+=a[i].y*sumx-a[i].x*sumy

最后记得除以2

谁能给我解释一下, 点坐标为什么开int过了,long long却过不了?


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 3010

using namespace std;

struct yts
{
	int x,y;
}a[maxn],t[maxn];

int n,m;
long long ans;

bool cmp(yts x,yts y)
{
	return x.y<y.y || (x.y==y.y && x.x<y.x);
}

bool cmp1(yts x,yts y)
{
	return x.x*y.y-x.y*y.x>0;
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1,cmp);
	for (int i=1;i<=n-2;i++)
	{
		int top=0;
		long long sumx=0,sumy=0;
		for (int j=i+1;j<=n;j++)
		{
			top++;t[top].x=a[j].x-a[i].x;t[top].y=a[j].y-a[i].y;
		}
		sort(t+1,t+top+1,cmp1);
		for (int j=1;j<=top;j++)
		{
			ans+=t[j].y*sumx-t[j].x*sumy;
			sumx+=t[j].x;sumy+=t[j].y;
		}
	}
	printf("%lld.%d\n",ans>>1,ans&1?5:0);
	return 0;
}


你可能感兴趣的:(【bzoj1132】[POI2008]Tro 计算几何)