CodeForces - 497D Gears

xiaoxiao2021-02-28  87

题目链接

分析: 如果固定了A不动,那么Q点则以P为圆心,PQ为半径做圆周运动。然后B与Q的相对位置保持不变。那么B上的任意一个点D,则绕着点P+QB,以PQ为半径做圆周运动。题目变成了A是否和B上任意一个顶点画的圆相交的问题了。判断A与圆相交是板子了。同理也固定B不动,A做圆周运动判一下。

代码:

#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <vector> #include <queue> #include <deque> #include <stack> #include <set> #include <cmath> using namespace std; struct Point { double x, y; Point (double x = 0, double y = 0) : x(x), y(y) {} }; struct Segment { Point A, B; Segment(Point a, Point b) : A(a), B(b) {} Segment(){} }; typedef Point Vector; Vector operator +(Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);} Vector operator -(Point A, Point B) {return Vector(A.x - B.x, A.y - B.y);} Vector operator *(Vector A, double p) {return Vector(A.x * p, A.y * p);} Vector operator /(Vector A, double p) {return Vector(A.x / p, A.y / p);} bool operator <(const Point &a, const Point &b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } const double eps = 1e-10; int dcmp(double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } bool operator ==(const Point &a, const Point &b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; } double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } double Length(Vector A) { return sqrt(Dot(A, A)); } double DistanceToSegment(Point P, Point A, Point B) { if (A == B) return (Length(P - A)); Vector v1 = B - A, v2 = P - A, v3 = P - B; if (dcmp(Dot(v1, v2)) < 0) return Length(v2); else if (dcmp(Dot(v1, v3)) > 0) return Length(v3); else return fabs(Cross(v1, v2)) / Length(v1); } double mDistanceToSegment(Point P, Point A, Point B) { double ans = -1; double tmp = Length(P - A); ans = max(ans, tmp); tmp = Length(P - B); ans = max(ans, tmp); return ans; } const int maxn = 1e3 + 5; Segment va[maxn], vb[maxn]; Point pa[maxn], pb[maxn]; int na, nb; Point P, Q; double R; bool check(Point p, Point q, Segment *a, int n, Point *b, int m) { for (int i = 0; i < m; i ++) { Point o = p + (b[i] - q); for (int j = 0; j < n; j ++) { double minv = DistanceToSegment(o, a[j].A, a[j].B); double maxv = mDistanceToSegment(o, a[j].A, a[j].B); if (minv <= R && R <= maxv) return false; } } return true; } int main(int argc, char const *argv[]) { cin>>P.x>>P.y; cin>>na; for (int i = 0; i < na; i ++) cin>>pa[i].x>>pa[i].y; cin>>Q.x>>Q.y; cin>>nb; for (int i = 0; i < nb; i ++) cin>>pb[i].x>>pb[i].y; R = Length(P - Q); va[0] = Segment(pa[0], pa[na - 1]); for (int i = 1; i < na; i ++) va[i] = Segment(pa[i - 1], pa[i]); vb[0] = Segment(pb[0], pb[nb - 1]); for (int i = 1; i < nb; i ++) vb[i] = Segment(pb[i - 1], pb[i]); if (check(P, Q, va, na, pb, nb) && check(Q, P, vb, nb, pa, na)) puts("NO"); else puts("YES"); return 0; }
转载请注明原文地址: https://www.6miu.com/read-54663.html

最新回复(0)