#define DeBUG
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <set>
#include <sstream>
#include <map>
#include <list>
#include <bitset>
#include <complex>
using namespace std ;
#define zero {0}
#define INF 0x3f3f3f3f
#define EPS 1e-9
#define TRUE true
#define FALSE false
typedef long long LL;
const double PI = acos(-1.0);
//#pragma comment(linker, "/STACK:102400000,102400000")
inline long long sgn(double x)
{
return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);
}
#define N 100005
template<class T> T sqr(T x)//求平方
{
return x * x;
}
// Point class
struct Point;
typedef Point Vec;
struct Point
{
long long x, y;
int id;
Point () {}
Point(long long a, long long b)
{
x = a;
y = b;
}
};
Vec operator - (const Vec &a, const Vec &b) //點減法
{
return Vec(a.x - b.x, a.y - b.y);
}
bool operator < (const Vec &a, const Point &b) //平面直角座標系中左下方的爲小
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline long long crossDet(Vec a, Vec b)//叉乘
{
return a.x * b.y - a.y * b.x;
}
Point origin;
bool cmp3(const Point &a, const Point &b)
{
long long ret = crossDet(a - origin, b - origin);
if (ret > 0)
return true;
return false;
}
double tan2num[3005];
bool cmp2(const Point &a, const Point &b)
{
double t1 = tan2num[a.id];
double t2 = tan2num[b.id];
if ( sgn(t1 - t2) == 0) return a.x - b.x<0;
return sgn(t1 - t2) < 0;
}
bool cmp(const Point &a, const Point &b)
{
if (a.x != b.x)return a.x < b.x;
return a.y < b.y;
}
long long dpget(Point *v, long long num)
{
if (num <= 1)
return 0;
long long ret = 0;
Point now = Point(0, 0);
for (long long i = 0; i < num; i++)
{
now.x += v[i].x;
now.y += v[i].y;
}
for (long long i = 0; i < num - 1; i++)
{
now.x -= v[i].x;
now.y -= v[i].y;
ret += crossDet(v[i], now);
}
return ret;
}
Point p[5000];
Point calp[5000];
Point v[5000];
int main()
{
#ifdef DeBUGs
freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);
#endif
long long T;
scanf("%I64d", &T);
while (T--)
{
long long n;
scanf("%I64d", &n);
for (long long i = 0; i < n; i++)
{
scanf("%I64d%I64d", &p[i].x, &p[i].y);
p[i].id = i;
}
stable_sort(p, p + n);
long long calpnum = 0;
long long ans = 0;
for (long long i = 0; i < n; i++)
{
calpnum = 0;
origin = p[i];
for (long long j = i + 1; j < n; j++)
{
calp[calpnum++] = p[j];
tan2num[p[j].id] = atan2(p[j].y - origin.y, p[j].x - origin.x);
}
stable_sort(calp, calp + calpnum, cmp2);//換成cmp3也可以
for (long long j = 0; j < calpnum; j++)
{
v[j] = calp[j] - origin;
}
// cout<<dpget(calp, calpnum)<<" "<<calpnum <<endl;
ans += dpget(v, calpnum);
}
printf("%I64d.%d\n", ans / 2, ans % 2 ? 5 : 0);
}
return 0;
}
優化g++ 6300ms不能再快了。。
#define DeBUG
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <set>
#include <sstream>
#include <map>
#include <list>
#include <bitset>
#include <complex>
using namespace std ;
#define zero {0}
#define INF 0x3f3f3f3f
#define EPS 1e-9
#define TRUE true
#define FALSE false
typedef long long LL;
const double PI = acos(-1.0);
//#pragma comment(linker, "/STACK:102400000,102400000")
inline long long sgn(double x)
{
return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);
}
#define N 100005
template<class T> T sqr(T x)//求平方
{
return x * x;
}
// Point class
struct Point;
typedef Point Vec;
struct Point
{
long long x, y;
int id;
Point () {}
Point(long long a, long long b)
{
x = a;
y = b;
}
};
Vec operator - (const Vec &a, const Vec &b) //點減法
{
return Vec(a.x - b.x, a.y - b.y);
}
bool operator < (const Vec &a, const Point &b) //平面直角座標系中左下方的爲小
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline long long crossDet( Vec a, Vec b)//叉乘
{
return a.x * b.y - a.y * b.x;
}
Point origin;
bool cmp3(const Point &a, const Point &b)
{
long long ret = crossDet(a - origin, b - origin);
if (ret > 0)
return true;
return false;
}
double tan2num[3005];
inline bool cmp2(const Point &a, const Point &b)
{
double t1 = tan2num[a.id];
double t2 = tan2num[b.id];
// if ( sgn(t1 - t2) == 0) return a.x - b.x<0;
return sgn(t1 - t2) < 0;
}
inline bool cmp(const Point &a, const Point &b)
{
if (a.x != b.x)return a.x < b.x;
return a.y < b.y;
}
inline long long dpget(Point *v, int num)
{
if (num <= 1)
return 0;
long long ret = 0;
Point now = Point(0, 0);
for (int i = 0; i < num; i++)
{
now.x += v[i].x;
now.y += v[i].y;
}
for (int i = 0; i < num - 1; i++)
{
now.x -= v[i].x;
now.y -= v[i].y;
ret += crossDet(v[i], now);
}
return ret;
}
Point p[3005];
Point v[3005];
int main()
{
#ifdef DeBUGs
freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);
#endif
int T;
scanf("%d", &T);
while (T--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%I64d%I64d", &p[i].x, &p[i].y);
p[i].id = i;
}
stable_sort(p, p + n, cmp);
int vnum = 0;
long long ans = 0;
for (int i = 0; i < n; i++)
{
vnum = 0;
origin = p[i];
for (int j = i + 1; j < n; j++)
{
v[vnum] = Vec(p[j].x - origin.x, p[j].y - origin.y);
v[vnum].id = p[j].id;
tan2num[p[j].id] = atan2((double)v[vnum].y, (double)v[vnum].x);
vnum++;
}
stable_sort(v, v + vnum, cmp2);
ans += dpget(v, vnum);
}
printf("%I64d.%d\n", ans / 2, ans % 2 ? 5 : 0);
}
return 0;
}