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