您的位置:首页 > 编程语言 > C语言/C++

PROBLEM_J: Gym 100345J - Zen Garden

2015-08-02 07:55 633 查看
/*PROBLEM C : DEAN AND SCHEDULE "SOLVED" */
/*TIME : ________________________________*/
#include "cstdio"
#include "cstring"
#include "cctype"
#include "algorithm"
#include "cmath"
#include "vector"
using namespace std;
#define Inc(i, a, b) for(int i = a; i < b; i++)
#define Dec(i, a, b) for(int i = a; i > b; i--)
#define Mem(a) memset(a, 0, sizeof(a))
#define Pii pair<int, int>
#define Pdd pair<double, double>
#define Cin scanf
#define Put printf
#define CIN(a) scanf("%d", &a)
#define CII(a, b) scanf("%d%d", &a, &b)
#define CIS(a) scanf("%s", a)
#define PUT(a) printf("%d\n", a)
#define PII(a, b) printf("%d %d\n", a, b)
#define PUS(a) printf("%s\n", a)
#define Pub push_back
#define Mpi make_pair
#define ll long long
#define maxn 100005
#define pi acos(-1)
#define eps 1e-10

struct Point {
double x, y;
Point() {}
Point(double x, double y) {
this->x = x, this->y = y;
}
Point operator + (const Point& p) const {
return Point(x + p.x, y + p.y);
}
Point operator - (const Point& p) const {
return Point(x - p.x, y - p.y);
}
Point operator * (const double& p) const {
return Point(x * p, y * p);
}
};
double Dot(Point a, Point b) {
return a.x * b.x + a.y * b.y;
}
double Length(Point a) {
return sqrt(a.x * a.x + a.y * a.y);
}
double Cross(Point a, Point b) {
return a.x * b.y - a.y * b.x;
}
Point Rotate(Point a, double rad) {
return Point(a.x * cos(rad) - a.y * sin(rad), a.x * sin(rad) + a.y * cos(rad));
}
struct Line {
Point a, b;
Line() {}
Line(Point a, Point b) {
this->a = a, this->b = b;
}
};
struct Circle {
Point o;
double r;
};
int dcmp(double x) {
if(abs(x) < eps) return 0;
return x > 0 ? 1 : -1;
}
int n, x, y;
Circle circle[15];
//Point points
vector<Line> lines;
bool Check(Point p) {
vector<Pdd> sets;
Inc(i, 0, n) {
if(dcmp(circle[i].r - Length(circle[i].o - p)) > 0) return 0;
double d = atan2(circle[i].o.y - p.y, circle[i].o.x - p.x);
double a = asin(circle[i].r / Length(circle[i].o - p));
sets.Pub(Mpi(d - a, d + a));
sets.Pub(Mpi(d - a + 2 * pi, d + a + 2 * pi));
sets.Pub(Mpi(d - a - 2 * pi, d + a - 2 * pi));
}
sort(sets.begin(), sets.end());
Inc(i, 1, sets.size())
if(dcmp(sets[i].first - sets[i - 1].second) < 0) return 0;
return 1;
}
Point Circs(int i, int j) {
double ox = (circle[i].o.x * circle[j].r + circle[j].o.x * circle[i].r) / (circle[i].r + circle[j].r);
double oy = (circle[i].o.y * circle[j].r + circle[j].o.y * circle[i].r) / (circle[i].r + circle[j].r);
return Point(ox, oy);
}
Point Solve() {
Inc(i, 0, lines.size()) Inc(j, i, lines.size()) {
double d = Cross(lines[i].b, lines[j].b);
if(dcmp(d)) {
double u = Cross(lines[j].b, lines[i].a - lines[j].a);
double t = u / d;
Point p = lines[i].a + lines[i].b * t;
if(dcmp(p.x) >= 0 && dcmp(p.y) >= 0 && dcmp(p.x - x) <= 0 && dcmp(p.y - y) <= 0)
if(Check(p)) return p;
}
}
return Point(-1, -1);
}
int main() {
freopen("zen.in", "r", stdin);
freopen("zen.out", "w", stdout);
CIN(n), CII(x, y);
Inc(i, 0, n) Cin("%lf %lf %lf", &circle[i].o.x, &circle[i].o.y, &circle[i].r);
lines.Pub(Line(Point(0, 0), Point(1.0 * x, 0)));
lines.Pub(Line(Point(x, 0), Point(1.0 * x, 1.0 * y)));
lines.Pub(Line(Point(0, y), Point(1.0 * x, 1.0 * y)));
lines.Pub(Line(Point(0, 0), Point(0, 1.0 * y)));
Inc(i, 0, n) Inc(j, i + 1, n) {
double d = asin((circle[i].r + circle[j].r) / Length(circle[i].o - circle[j].o));
Point p = Circs(i, j);
lines.Pub(Line(p, Rotate(circle[i].o - circle[j].o, d)));
lines.Pub(Line(p, Rotate(circle[i].o - circle[j].o, -d)));
}
Point p = Solve();
if(p.x < 0) PUS("No Zen\n");
else Put("%.10f %.10f\n", p.x, p.y);
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 代码 ACM