有没有ikun可以帮蒟蒻调旋转卡壳WA#10#14
查看原帖
有没有ikun可以帮蒟蒻调旋转卡壳WA#10#14
817044
cjwdyzxfblzs楼主2023/6/13 09:25

感觉是判断凸包的时候没有判断相同纵坐标的情况,但是不知道怎么改了欸,已经调了一晚上加一上午了,悲


#include <bits/stdc++.h>
using namespace std;
#define INF32_MAX 2147483647
const int N = 1e6;

/* Geometry objects */
struct Point { double x, y; };    /* point */
using Vec = Point;    /* vector */
struct Line { Point P; Vec v; };    /* line */
struct Seg { Point A, B; };    /* segment */
struct Circle { Point O; double r; };    /* circle */

/* constant */
const Point O = {0, 0};
const Line Ox = {O, {1, 0}}, Oy = {O, {0, 1}};
const double PI = acos(-1), eps = 1e-8;

bool eq(double a, double b) { return abs(a - b) < eps; }  // ==
bool gt(double a, double b) { return a - b > eps; }       // >
bool lt(double a, double b) { return a - b < -eps; }      // <
bool ge(double a, double b) { return a - b > -eps; }      // >= 
bool le(double a, double b) { return a - b < eps; }       // <=
Vec operator+(Vec u, Vec v) { return {u.x + v.x, u.y + v.y}; }
Vec operator-(Vec u, Vec v) { return {u.x - v.x, u.y - v.y}; }
Vec operator*(double k, Vec v) { return {k * v.x, k * v.y}; }
Vec operator/(Vec A, double p) { return {A.x / p, A.y / p}; }
double operator*(Vec u, Vec v) { return u.x * v.x + u.y * v.y; }
double operator^(Vec u, Vec v) { return u.x * v.y - u.y * v.x; } // cross ⇩
double Len(Vec v) { return sqrt(v.x * v.x + v.y * v.y); }
double cross(Vec A, Vec B) { return A.x * B.y - A.y * B.x; } 
double calc(Point p, Point q, Point r) { return (q - p) ^ (r - q); }  
bool operator==(Point A, Point B) { return eq(A.x, B.x) and eq(A.y, B.y); }
bool operator<(Point X, Point Y) { return lt(X.x, Y.x) or (eq(X.x, Y.x) and lt(X.y, Y.y)); }/*是不是这个的问题啊???*/
double dis(Point A, Point B) { return Len(A - B); }
/*-------------------------------------------------------------------------------*/
using Points = vector<Point>;
double theta(Point p) { return p == O ? -1 / 0. : atan2(p.y, p.x); }    // 求极角
void psort(Points &ps, Point c = O)     // 极角排序
{
    sort(ps.begin(), ps.end(), [&](auto p1, auto p2) { return lt(theta(p1 - c), theta(p2 - c)); });
}
bool check(Point p, Point q, Point r) { return lt(0, (q - p) ^ (r - q)); }    // 检查是不是逆时针旋转的
Points chull(Points &ps)
{
    psort(ps, *min_element(ps.begin(), ps.end()));
    Points H{ps[0]};
    for (int i = 1; i < ps.size(); i ++ )
    {
        while (H.size() > 1 && !check(H[H.size() - 2], H.back(), ps[i]))
            H.pop_back();
        H.push_back(ps[i]);
    }
    H.push_back(ps[0]);
    return H;
}
Points P;
 // 这里是因为我上面用double求的,题目要求是int,就重新复制一下了
struct point{
    int x, y;
}p[N], s[N];
int cnt;
inline int dis(point a, point b){
	return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
inline int space(point a, point b, point c){
	return ((a.x * b.y + b.x * c.y + c.x * a.y) - (a.x * c.y + b.x * a.y + c.x * b.y)) / 2;
}
signed main()
{
    // freopen("ans.in", "r", stdin);
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i ++ )
    {
        double x, y;
        scanf("%lf%lf", &x, &y);
        P.push_back({x, y});
    }
    Points H = chull(P);
    for (auto v : H)
        s[++ cnt].x = v.x, s[cnt].y = v.y;
    cnt -- ;
    int maxn = -1;
    if(cnt == 2){
        printf("%d\n", dis(s[1], s[2]));
        return 0;
    }
    int j = 3;
    for(int i = 1; i <= cnt; ++ i ){
        maxn = max(maxn, dis(s[i], s[i + 1]));
        while(space(s[i], s[i + 1], s[j]) < space(s[i], s[i + 1], s[j % cnt + 1]))
            j = j % cnt + 1;
        maxn = max(maxn, max(dis(s[i], s[j]), dis(s[i + 1], s[j])));
    }
    printf("%d\n", maxn);

    return 0;
}

2023/6/13 09:25
加载中...