select three points to make a triangle calculate total S-極角排序與向量

#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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章