UVALive 4127
来源:互联网 发布:怎样注册淘宝号 编辑:程序博客网 时间:2024/06/08 11:35
Link:click here
The question:给出n座山的高和宽,山视为等腰三角形,从上往下看,求山的轮廓的长度,山之间的空白不算。
Solution:用竖线在山与山的交点和顶点处,把所有山分成一段一段的的线段,统计竖线内每段线段的长度,累加即可。先把所有端点的横坐标放入数组X里, 然后对线段两两求交,把交点的横坐标也放入数组X里,然后排序去重。求出每条线段与竖线的交点的y坐标的最大值,因为竖线可能与多条线段相交,但只有最 上面的点是可见的。
Conclusion:判断直线相交改为判断直线不平行会简化很多,同时用到了离散化的思想
Code:
#include <bits/stdc++.h>using namespace std;const double eps = 1e-7;typedef struct Point{ double x, y; Point(double x = 0.0, double y = 0.0): x(x), y(y) {}} Vector;struct Line{ Point a, b; Line() {} Line(Point a, Point b): a(a), b(b) {}} L[5000];Vector operator + (Vector A, Vector B){ return Vector(A.x + B.x, A.y + B.y);}Vector operator - (Vector A, Vector B){ return Vector(A.x - B.x, A.y - B.y);}Vector operator * (Vector A, double t){ return Vector(A.x * t, A.y * t);}Vector operator / (Vector A, double t){ return Vector(A.x / t, A.y / t);}int dcmp(double x){ if (fabs(x) < eps) return 0; return x < 0.0 ? -1 : 1;}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;}bool segment(Point a1, Point a2, Point b1, Point b2){ return dcmp(Cross(a1 - a2, b1 - b2)) != 0;}Point get(Point p, Vector v, Point q, Vector w){ Vector u = p - q; double t = Cross(w, u) / Cross(v, w); return p + v * t;}bool onsegment(Point p, Point a1, Point a2){ return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) <= 0;}int dex = 0, fix = 0;double H(double x)//求横坐标为x时,对应的线段上的y坐标的最大值{ double ans = 0.0; for (int i = 0; i < dex; i++) { if (segment(Point(x, -1000.0), Point(x, 1000.0), L[i].a, L[i].b)) { Point tmp = get(Point(x, -1000.0), Vector(0.0, 2000), L[i].a, Vector(L[i].b - L[i].a)); if (onsegment(tmp, L[i].a, L[i].b)) { ans = max(ans, tmp.y); } } } return ans;}double X[500000];int main(){ int n, cas = 1; while (scanf("%d", &n), n) { dex = fix = 0; for (int i = 0; i < n; i++) { double x, h, b; scanf("%lf%lf%lf", &x, &h, &b); L[dex++] = Line(Point(x - 0.5 * b, 0.0), Point(x, h)); L[dex++] = Line(Point(x, h), Point(x + 0.5 * b, 0.0)); X[fix++] = x - 0.5 * b; X[fix++] = x; X[fix++] = x + 0.5 * b; } for (int i = 0; i < dex; i++)//求山与山与上的交点的横坐标 { for (int j = i + 1; j < dex; j++) { if (segment(L[i].a, L[i].b, L[j].a, L[j].b))//如果相交 { Point tmp = get(L[i].a, L[i].b - L[i].a, L[j].a, L[j].b - L[j].a);//求交点 if (onsegment(tmp, L[i].a, L[i].b))//交点在线段上 { X[fix++] = tmp.x; } } } } sort(X, X + fix);//排序 fix = unique(X, X + fix) - X;//去重 double preh = H(X[0]); double ans = 0.0; for (int i = 1; i < fix; i++)//求所有竖线区间内的线段和 { double nowh = H(X[i]); double disx = fabs(X[i] - X[i - 1]); double disy = fabs(nowh - preh); if (dcmp(preh) || dcmp(nowh))//判断是不是同一个点 { ans += sqrt(disx * disx + disy * disy); } preh = nowh; } printf("Case %d: %.0f\n\n", cas++, ans); } return 0;}
0 0
- UVALive 4127
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- 找工作——jvm复习(一)
- HDU 1509 windows message queue
- 电子工程师最关心的10个问题,看完有答案没?
- ubuntu 安装qt4
- 如何在Xib中添加自定义的属性?
- UVALive 4127
- nginx配置ssl
- 专题一 · 1005
- 待完善知识点
- 有关小波变换的介绍
- Java Web 下彻底解决MySQL 8 小时问题
- 数据库中的VARCHAR(M)及其他变长类型
- SVM支持向量机原理(一)
- Activity与Fragment的生命周期详解