MnZn 求助旋转卡壳
查看原帖
MnZn 求助旋转卡壳
319671
Reliauk楼主2022/1/24 00:58

51pts

WA on #1,#5,#6,#8,#9,#10,#11

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <vector>

using std::cin;
using std::cout;

namespace Geometry {
typedef double db;
#define il inline
#define ilb il bool
#define ild il db
const db eps = 1e-8;
il int sign(db x) { return x < -eps ? -1 : (x > eps ? 1 : 0); }
ild getAbs(db x) { return x * sign(x); }

struct Point {
  db x, y;
  Point(db a = 0, db b = 0) { x = a, y = b; }
};
typedef Point Vector;
bool operator==(Point a, Point b) {
  return !sign(a.x - b.x) && !sign(a.y - b.y);
}
il Vector operator+(Vector a, Vector b) { return Vector(a.x + b.x, a.y + b.y); }
il Vector operator-(Vector a, Vector b) { return Vector(a.x - b.x, a.y - b.y); }
il Vector operator*(Vector a, db k) { return Vector(a.x * k, a.y * k); }
ild dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
ild cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
ild length(Vector a) { return (dot(a, a)); }
il Vector clockwise(Vector a, db theta) {
  db x = a.x * std::cos(theta) + a.y * std::sin(theta);
  db y = a.y * std::cos(theta) - a.x * std::sin(theta);
  return Point(x, y);
}
il Vector clockwise(Vector a, Point ori, db theta) {
  return clockwise(a - ori, theta);
}

struct Segment {
  Point l, r;
  Segment(Point a = Point(), Point b = Point()) { l = a, r = b; }
};
struct Line {
  Point l, r;
  Line(Point a = Point(), Point b = Point()) { l = a, r = b; }
  Line(Segment x) { l = x.l, r = x.r; }
};
ilb isBelong(Point a, Segment b) {
  return !sign(cross(a - b.l, b.r - b.l)) && sign(dot(a - b.l, a - b.r)) <= 0;
}
ilb isBelong(Point a, Line b) { return !sign(cross(a - b.l, b.r - b.l)); }
il Point getFoot(Point a, Line b) {
  Vector x = a - b.l, y = a - b.r, z = b.r - b.l;
  db a1 = dot(x, z) / length(z), a2 = -1.0 * dot(y, z) / length(z);
  return a + z * (1.0 * a1 / (a1 + a2));
}
il Point getFoot(Point a, Segment b) {
  if (b.l == b.r) return b.l;
  Vector x = a - b.l, y = a - b.r, z = b.r - b.l;
  if (sign(dot(x, z)) < 0) return b.l;
  if (sign(dot(y, z)) > 0) return b.r;
  return getFoot(a, Line(b));
}
ild dis(Point a, Segment b) {
  if (b.l == b.r) return length(a - b.l);
  Vector x = a - b.l, y = a - b.r, z = b.r - b.l;
  if (sign(dot(x, z)) < 0) return length(x);
  if (sign(dot(y, z)) > 0) return length(y);
  return getAbs(cross(x, z) / length(z));
}
ild dis(Point a, Line b) { return length(getFoot(a, b) - a); }
il Point sym(Point a, Line b) { return a + (getFoot(a, b) - a) * 2; }
il Point sym(Point a, Segment b) { return sym(a, Line(b)); }
il Point inter(Line a, Line b) {
  Vector x = a.r - a.l, y = b.r - b.l, z = a.l - b.l;
  return a.l + x * (cross(y, z) / cross(x, y));
}
il Point inter(Segment a, Segment b) { return inter(Line(a), Line(b)); }
il Point inter(Line a, Segment b) { return inter(a, Line(b)); }
il Point inter(Segment a, Line b) { return inter(Line(a), b); }
ilb hasInter(Line a, Segment b) { return isBelong(inter(a, b), b); }
ilb hasInter(Segment a, Line b) { return isBelong(inter(a, b), a); }
ilb hasInter(Segment a, Segment b) {
  db c1 = cross(a.r - a.l, b.l - a.l), c2 = cross(a.r - a.l, b.r - a.l);
  db d1 = cross(b.r - b.l, a.l - b.l), d2 = cross(b.r - b.l, a.r - b.l);
  return sign(c1) * sign(c2) < 0 && sign(d1) * sign(d2) < 0;
}

typedef std::vector<Point> Polygon;

inline int isIn(Point a, Polygon b) {
  int cnt = 0, n = b.size();
  for (int i = 0; i < n; ++i) {
    int j = (i + 1) % n;
    if (isBelong(a, Segment(b[i], b[j]))) return 2;
    if (a.y < std::min(b[i].y, b[j].y) || a.y >= std::max(b[i].y, b[j].y))
      continue;
    db tmp = b[i].x + (a.y - b[i].y) / (b[j].y - b[i].y) * (b[j].x - b[i].x);
    cnt += sign(tmp - a.x) > 0;
  }
  return cnt & 1;
}
ilb check(Point a, Point b, Point c) { return sign(cross(b - a, c - a)) > 0; }
inline int isInConvex(Point a, Polygon b) {
  int n = b.size();
  if (check(b[0], a, b[1]) || check(b[0], b[n - 1], a)) return 0;
  if (isBelong(a, Segment(b[0], b[1])) || isBelong(a, Segment(b[0], b[n - 1])))
    return 2;
  int l = 1, r = n - 2;
  while (l < r) {
    int mid = l + r + 1 >> 1;
    if (check(b[0], b[mid], a))
      l = mid;
    else
      r = mid - 1;
  }
  if (isBelong(a, Segment(b[l], b[l + 1]))) return 2;
  return !check(b[l], a, b[l + 1]);
}
ilb polyInter(Polygon a, Polygon b) {
  int n = a.size(), m = b.size();
  for (int i = 0; i < n; ++i) {
    int ni = (i + 1) % n;
    for (int j = 0; j < m; ++j) {
      int nj = (j + 1) % m;
      if (hasInter(Segment(a[i], a[ni]), Segment(b[j], b[nj]))) return 0;
      if (isIn(a[i], b) || isIn(b[j], a)) return 0;
    }
  }
  return 1;
}
ilb convexInter(Polygon a, Polygon b) {
  int n = a.size(), m = b.size();
  for (int i = 0; i < n; ++i) {
    int ni = (i + 1) % n;
    for (int j = 0; j < m; ++j) {
      int nj = (j + 1) % m;
      if (hasInter(Segment(a[i], a[ni]), Segment(b[j], b[nj]))) return 0;
      if (isInConvex(a[i], b) || isInConvex(b[j], a)) return 0;
    }
  }
  return 1;
}
ild area(Polygon p) {
  int n = p.size();
  db s = 0;
  for (int i = 0; i < n; ++i) s += cross(p[i], p[(i + 1) % n]) / 2.0;
  return s;
}
Polygon convexHull(Polygon p) {
  Polygon a = p;
  std::sort(a.begin(), a.end(), [](Vector a, Vector b) {
    return a.x == b.x ? a.y < b.y : a.x < b.x;
  });
  int n = a.size();
  std::vector<Point> s;
  for (int i = 0; i < n; ++i) {
    while (s.size() > 1 &&
           sign(cross(s[s.size() - 2] - s.back(), a[i] - s[s.size() - 2])) <= 0)
      s.pop_back();
    s.push_back(a[i]);
  }
  int cur = s.size();
  for (int i = n - 2; ~i; --i) {
    while (s.size() > cur &&
           sign(cross(s[s.size() - 2] - s.back(), a[i] - s[s.size() - 2])) <= 0)
      s.pop_back();
    s.push_back(a[i]);
  }
  s.pop_back();
  return s;
}
ild diameter(Polygon p) {
  int n = p.size();
  db ans = length(p[1] - p[0]);
  if (n == 2) return ans;
  for (int i = 0, j = 2; i < n; ++i) {
    while (sign(cross(p[(i + 1) % n] - p[i], p[j] - p[i]) -
                cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[i])) < 0)
      j = (j + 1) % n;
    ans = std::max(
        ans, std::max(length(p[j] - p[i]), length(p[j] - p[(i + 1) % n])));
  }
  return ans;
}

};  // namespace Geometry

using namespace Geometry;

int n;
Polygon p;

int main() {
  cin >> n;
  while (n--) {
    int x, y;
    cin >> x >> y;
    p.emplace_back(Point(x, y));
  }
  int x = diameter(convexHull(p));
  cout << (int)(x) << '\n';
  return 0;
}

上面的模板应该没错,但看起来好像问题在 diameter()

求调/kk

2022/1/24 00:58
加载中...