cf1017E

判断两个凸包是否同构

首先将两个点集都求凸包,然后根据边角边建立两个串。接下来就是double类型的最小表示法。。魔改一下就好了。。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 1e5 + 5;
const double EPS = 1e-6;
const int INF = 0x7fffffff;
struct Point
{
    Point() {}
    Point(double _x, double _y): x(_x), y(_y) {}
    double getDis(Point rhs)
    {
        double xx = rhs.x - x;
        double yy = rhs.y - y;
        return sqrt(xx * xx + yy * yy);
    }
    void input()
    {
        scanf("%lf%lf", &x, &y);
    }

    bool operator <(Point &rhs)
    {
        if(fabs(y - rhs.y) <= EPS) return x < rhs.x;
        return y < rhs.y;
    }
    double x, y;
    double v, l;
    int id;
};
Point operator -(Point lhs, Point rhs){return Point(rhs.x - lhs.x, rhs.y - lhs.y);}
double operator ^(Point lhs, Point rhs){return lhs.x * rhs.y - lhs.y * rhs.x;}
double operator *(Point lhs, Point rhs){return lhs.x * rhs.x + lhs.y * rhs.y;}

Point src1, src2, src;
int n, m;

bool cmp(Point &a, Point &b)
{
    double temp = (a - src) ^ (b - src);
    if(fabs(temp) <= EPS) return a.getDis(src) < b.getDis(src);
    return temp > 0;
}

int stack[MAXN];
void getConvex(vector<Point> &a, vector<Point> &out)
{
    out.clear();
    sort(a.begin(), a.end(), cmp);

    stack[0] = 0;
    stack[1] = 1;
    int top = 1;
    for(int i = 2; i < (int)a.size(); ++i)
    {
        while(top >= 1 && ((a[i] - a[stack[top - 1]]) ^ (a[stack[top]] - a[stack[top - 1]])) >= 0)
        {
            --top;
        }
        stack[++top] = i;
    }
    for(int i = 0; i <= top; ++i) out.push_back(a[stack[i]]);
}

vector<Point> c1, c2, a1, a2;

vector<double> d1, d2;
vector<double> r1, r2;

void smallrep(vector<double> &d, vector<double> &out)
{
    int i, j, k, l;
    int n = (int)d.size();
    for(i = 0; i < n; ++i)
    {
        d.push_back(d[i]);
    }
    for(i = 0, j = 1; j < n;)
    {
        for(k = 0; k < n && fabs(d[i + k] - d[j + k]) <= EPS; ++k);
        if(k >= n) break;
        if(d[i + k] < d[j + k]) j += k + 1;
        else
        {
            l = i + l;
            i = j;
            j = max(l, j) + 1;
        }
    }
    out.clear();
    for(int t = i; t < i + n; ++t)
    {
        out.push_back(d[t]);
    }
}

void smallest(vector<double> &d, vector<double> &out)
{
    int n = (int)d.size();
    for(int i = 0; i < n; ++i)
    {
        d.push_back(d[i]);
    }
    int i = 0, p = 1;
    while(i < n && p < n)
    {
        int k = 0;
        while(fabs(d[i + k] - d[p + k]) <= EPS) ++k;
        if(k >= n) break;

            if(d[i + k] > d[p + k]) i = max(i + k + 1, p + 1);
            else p = max(p + k + 1, i + 1);
    }
    i = min(i, p);
    for(int t = i; t < i + n; ++t)
    {
        out.push_back(d[t]);
    }
}

bool small()
{
    int n = c1.size(), m = c2.size();
    if(n != m) return false;
    for(int i = 0; i < n; ++i)
    {
        int nxt = (i + 1) % n;
        int pre = (i - 1 + n) % n;
        Point preVec = c1[pre] - c1[i];
        Point nxtVec = c1[nxt] - c1[i];
        d1.push_back(c1[i].getDis(c1[nxt]));
        d1.push_back(fabs(preVec * nxtVec));
    }
    for(int i = 0; i < m; ++i)
    {
        int nxt = (i + 1) % m;
        int pre = (i - 1 + n) % n;
        Point preVec = c2[pre] - c2[i];
        Point nxtVec = c2[nxt] - c2[i];
        d2.push_back(c2[i].getDis(c2[nxt]));
        d2.push_back(fabs(preVec * nxtVec));
    }
    smallest(d1, r1);
    smallest(d2, r2);
    n = r1.size();
    for(int i = 0; i < n; ++i)
    {
        if(fabs(r1[i] - r2[i]) >= EPS) return false;
    }
    return true;
}

int main()
{
    scanf("%d%d", &n, &m);
    Point temp;
    for(int i = 1; i <= n; ++i)
    {
        temp.input();
        a1.push_back(temp);
        if(i == 1) src1 = temp;
        else
        {
            if(temp < src1) src1 = temp;
        }
    }
    for(int i = 1; i <= m; ++i)
    {
        temp.input();
        a2.push_back(temp);
        if(i == 1) src2 = temp;
        else
        {
            if(temp < src2) src2 = temp;
        }
    }
    src = src1;
    getConvex(a1, c1);
    src = src2;
    getConvex(a2, c2);
    if(small()) puts("YES");
    else puts("NO");
}