您的位置:首页 > 其它

CodeForces - 497D Ge 4000 ars

2017-05-06 14:41 211 查看
题目链接

分析:

如果固定了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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: