栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

zoj 3012 Tower

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

zoj 3012 Tower

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <map>using namespace std;const double eps = 1e-8;const double pi = acos(-1.0);int sgn(double d) { if (d > eps) return 1; if (d < -eps) return -1; return 0;}struct point { double x, y; point(double _x = 0, double _y = 0): x(_x), y(_y) { }};bool operator==(const point& p1, const point& p2) { return sgn(p1.x - p2.x) == 0 && sgn(p1.y - p2.y) == 0;}bool operator!=(const point& p1, const point& p2) { return !(p1 == p2);}bool operator<(const point& p1, const point& p2) { return sgn(p1.x - p2.x) == 0 ? sgn(p1.y - p2.y) < 0 : p1.x < p2.x;}point operator+(const point& p1, const point& p2) { return point(p1.x + p2.x, p1.y + p2.y);}point operator-(const point& p1, const point& p2) { return point(p1.x - p2.x, p1.y - p2.y);}double operator^(const point& p1, const point& p2) { return p1.x * p2.x + p1.y * p2.y;}double operator*(const point& p1, const point& p2) { return p1.x * p2.y - p1.y * p2.x;}struct polygon { int n; point p[8];};struct event { double k; event(double _k = 0): k(_k) { }};bool operator<(const event& e1, const event& e2) { return sgn(e1.k - e2.k) < 0;}int n, n_pol;double rate;double R[160], H[160];polygon pol[320];map<event, double> mp;bool solve();void add_pol(int id);void to_normal(polygon& pol);double get_area();void update(const point& p);void add_pol(int id1, int id2);double get_area(int id, const point& p1, const point& p2);int get_intersection(const point& p1, const point& p2, const point& p3, const point& p4, point& c);bool is_valid(int id, const point& p1, const point& p2);bool is_inside(const point& p, int id);int main() { while (solve()); return 0;}bool solve() { if (scanf("%d%lf", &n, &rate) == EOF) return false; n_pol = 0; for (int i = 0; i <= n; ++i) { scanf("%lf%lf", &R[i], &H[i]); add_pol(i); } printf("%.4lfn", get_area()); return true;}void add_pol(int id) { polygon& cur = pol[n_pol]; cur.n = 0; for (int i = 0; i < 6; ++i) { point p(R[id] * cos(i * pi / 3.0), R[id] * sin(i * pi / 3.0)); p.y += H[id] * rate; cur.p[cur.n++] = p; } to_normal(cur); if (cur.n > 2) ++n_pol;}void to_normal(polygon& pol) { pol.n = unique(pol.p, pol.p + pol.n) - pol.p; while (pol.n > 1 && pol.p[0] == pol.p[pol.n - 1]) --pol.n;}double get_area() { vector<double> vec; vector<pair<point, point> > seg; for (int i = 0; i < n_pol; ++i) { seg.push_back(make_pair(pol[i].p[4], pol[i].p[3])); seg.push_back(make_pair(pol[i].p[3], pol[i].p[2])); vec.push_back(pol[i].p[4].y); vec.push_back(pol[i].p[3].y); vec.push_back(pol[i].p[2].y); } int tmp = n_pol; for (int i = 0; i < n; ++i) add_pol(i, i + 1); for (int i = tmp; i < n_pol; ++i) { seg.push_back(make_pair(pol[i].p[0], pol[i].p[pol[i].n - 1])); vec.push_back(pol[i].p[0].y); vec.push_back(pol[i].p[pol[i].n - 1].y); } for (int i = 0; i < seg.size(); ++i) { for (int j = i + 1; j < seg.size(); ++j) { point c; if (get_intersection(seg[i].first, seg[i].second, seg[j].first, seg[j].second, c)) vec.push_back(c.y); } } sort(vec.begin(), vec.end()); vector<double> vec2; vec2.push_back(vec.front()); for (int i = 1; i < vec.size(); ++i) if (sgn(vec[i] - vec[i - 1]) != 0) vec2.push_back(vec[i]); double area = 0; for (int i = 0; i < vec2.size() - 1; ++i) { double y1 = vec2[i], y2 = vec2[i + 1]; double x1 = 0, x2 = 0; for (int j = 0; j < seg.size(); ++j) { if (sgn(seg[j].first.y - y1) <= 0 && sgn(seg[j].second.y - y2) >= 0) { x1 = min(x1, seg[j].first.x + (seg[j].second.x - seg[j].first.x) * (y1 - seg[j].first.y) / (seg[j].second.y - seg[j].first.y)); x2 = min(x2, seg[j].first.x + (seg[j].second.x - seg[j].first.x) * (y2 - seg[j].first.y) / (seg[j].second.y - seg[j].first.y)); } } area += (x1 + x2) * (y1 - y2); } return abs(area);}void update(const point& p) { event e(p.y); if (mp.find(e) == mp.end()) mp[e] = p.x; else { double tmp = mp[e]; if (p.x < tmp) mp[e] = p.x; }}void add_pol(int id1, int id2) { polygon& cur = pol[n_pol]; cur.n = 4; cur.p[0] = point(-R[id2], 0 + H[id2] * rate); cur.p[1] = point(R[id2], 0 + H[id2] * rate); cur.p[2] = point(R[id1], 0 + H[id1] * rate); cur.p[3] = point(-R[id1], 0 + H[id1] * rate); to_normal(cur); if (cur.n > 2) ++n_pol;}double get_area(int id, const point& p1, const point& p2) { vector<point> vec; vec.push_back(p1); vec.push_back(p2); for (int i = 0; i < n_pol; ++i) { if (i == id) continue; for (int j = 0; j < pol[i].n; ++j) { point c; int tmp = get_intersection(p1, p2, pol[i].p[j], pol[i].p[(j + 1) % pol[i].n], c); if (tmp == 1) { vec.push_back(c); } else if (tmp == -1) { } } } sort(vec.begin(), vec.end()); vec.resize(unique(vec.begin(), vec.end()) - vec.begin()); if (vec.front() != p1) reverse(vec.begin(), vec.end()); double area = 0; for (int i = 0; i < (int)vec.size() - 1; ++i) { if (is_valid(id, vec[i], vec[i + 1])) area += vec[i] * vec[i + 1]; } return area / 2.0;}int get_intersection(const point& p1, const point& p2, const point& p3, const point& p4, point& c) { double d1 = (p2 - p1) * (p3 - p1), d2 = (p2 - p1) * (p4 - p1); double d3 = (p4 - p3) * (p1 - p3), d4 = (p4 - p3) * (p2 - p3); int s1 = sgn(d1), s2 = sgn(d2), s3 = sgn(d3), s4 = sgn(d4); if (s1 == 0 && s2 == 0 && s3 == 0 && s4 == 0) return -1; c = point((p3.x * d2 - p4.x * d1) / (d2 - d1), (p3.y * d2 - p4.y * d1) / (d2 - d1)); return (s1 * s2 <= 0 && s3 * s4 <= 0) ? 1 : 0;}bool is_valid(int id, const point& p1, const point& p2) { point p((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0); for (int i = 0; i < n_pol; ++i) if (i != id && is_inside(p, i)) return false; return true;}bool is_inside(const point& p, int id) { for (int i = 0; i < pol[id].n; ++i) { point p1 = pol[id].p[i], p2 = pol[id].p[(i + 1) % pol[id].n]; if (sgn((p2 - p1) * (p - p1)) < 0) return false; } return true;}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/379644.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号