HDU4637 Rain on your Fat brother
来源:互联网 发布:软件二次开发端口 编辑:程序博客网 时间:2024/06/10 00:23
任意门: http://acm.hdu.edu.cn/showproblem.php?pid=4637
假设所有雨点都不动,那么可以看做人物向着左上角匀速移动。
求出人物运动的轨迹(一条线段)与所有雨滴的交线段,然后求线段并就可以了。
题目其实很简单,但是很烦啊,记录一下代码。
#pragma comment(linker,"/STACK:102400000,102400000")#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <ctime>#include <vector>#include <set>#include <queue>#include <stack>#include <map>#include <algorithm>using namespace std;typedef long long ll;const double eps = 1e-8;const double PI = acos(-1.0);struct Point{double x, y;Point(double x=0, double y=0): x(x), y(y) {}};typedef Point Vector;void print(Point p) {cout << p.x << " " << p.y << endl;}bool operator < (const Point &a, const Point &b) {return a.x > b.x || (a.x == b.x && a.y < b.y);}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;}bool operator != (const Point &a, const Point &b) {return !(a == b);}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 p) {return Vector(A.x*p, A.y*p);}Vector operator / (Vector A, double p) {return Vector(A.x/p, A.y/p);}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 Distance(Point A, Point B) {return sqrt(Dot(A-B, A-B));}double Area2(Point A, Point B, Point C) {return abs(Cross(B-A, C-A));}bool OnSegment(Point P, Point A, Point B){return dcmp(Cross(A-P, B-P))==0 && dcmp(Dot(A-P, B-P))<0;}bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1), c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;}Point GetLineIntersection(Point a1, Point a2, Point b1, Point b2){Vector v = a2-a1, w = b2-b1, u = a1-b1;double t = Cross(w, u) / Cross(v, w);return a1 + v*t;}struct Circle{ Point c; double r; Circle() {c = Point(0, 0); r = 0;} Circle(Point c, double r) : c(c), r(r) {} Point point(double a) {return Point(c.x + r*cos(a), c.y + r*sin(a));}};int GetLineCircleIntersection(Point A, Point B, Circle C, Point &X, Point &Y){ double a = (B-A).x, b = A.x-C.c.x, c = (B-A).y, d = A.y-C.c.y; double e = a*a+c*c, f = 2*(a*b+c*d), g = b*b+d*d-C.r*C.r; double delta = f*f - 4*e*g; if (dcmp(delta) < 0) return 0; else if (dcmp(delta) == 0) { double tt = -f / (2*e); X = A + (B-A)*tt; if (dcmp(X.y - C.c.y) > 0 || dcmp(X.y - A.y) < 0 || dcmp(X.y - B.y) > 0) return 0; return 1; } else { int ret = 0; double t1 = (-f - sqrt(delta)) / (2*e); X = A + (B-A)*t1; if (dcmp(X.y - C.c.y) > 0 || dcmp(X.y - A.y) < 0 || dcmp(X.y - B.y) > 0) { t1 = (-f + sqrt(delta)) / (2*e); X = A + (B-A)*t1; if (dcmp(X.y - C.c.y) > 0 || dcmp(X.y - A.y) < 0 || dcmp(X.y - B.y) > 0) return 0; return 1; } ret++; double t2 = (-f + sqrt(delta)) / (2*e); Y = A + (B-A)*t2; if (dcmp(Y.y - C.c.y) > 0 || dcmp(Y.y - A.y) < 0 || dcmp(Y.y - B.y) > 0) return ret; ret++; return ret; }}const int maxn = 1010;int T, cas = 1, n, tot;double v1, v2, v0, dt, sx, t;double xx, yy, r, h;Point ST, ED;Vector v;struct Seg{ double x1, x2; Seg(double x1=0, double x2=0) : x1(x1), x2(x2) {} bool operator < (const Seg &o) const { return x1 > o.x1;}}s[maxn];bool inside(Point p, Point A, Point B, Point C, Circle c){ if (dcmp(Area2(p, A, B) + Area2(p, A, C) + Area2(p, B, C) - Area2(A, B, C)) == 0) return 1; if (dcmp(Distance(p, c.c) - c.r) <= 0 && dcmp(p.y - c.c.y) <= 0) return 1; return 0;}int main(){ scanf("%d", &T); while (T--) { scanf("%lf%lf%lf%lf%lf",&v1,&v2,&v0,&dt,&sx); t = dt + v1*dt/(v2-v1); v = Vector(-v1, v0); ST = Point(sx, 0); ED = ST + v*t; tot = 0; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&xx,&yy,&r,&h); Point A = Point(xx, yy+h); Point B = Point(xx-r, yy); Point C = Point(xx+r, yy); Circle c = Circle(Point(xx, yy), r); int cnt = 0, ttmp; double tmp[10]; Point tmp1, tmp2; if (OnSegment(A, ST, ED)) tmp[cnt++] = A.x; if (OnSegment(B, ST, ED)) tmp[cnt++] = B.x; if (OnSegment(C, ST, ED)) tmp[cnt++] = C.x; if (SegmentProperIntersection(ST, ED, A, B)) tmp[cnt++] = GetLineIntersection(ST, ED, A, B).x; if (SegmentProperIntersection(ST, ED, A, C)) tmp[cnt++] = GetLineIntersection(ST, ED, A, C).x; if ((ttmp = GetLineCircleIntersection(ST, ED, c, tmp1, tmp2)) > 0) { tmp[cnt++] = tmp1.x; if (ttmp == 2) tmp[cnt++] = tmp2.x; } if (inside(ST, A, B, C, c)) tmp[cnt++] = ST.x; if (inside(ED, A, B, C, c)) tmp[cnt++] = ED.x; if (cnt >= 2) { sort(tmp, tmp+cnt); s[tot++] = Seg(tmp[cnt-1], tmp[0]); } } sort(s, s+tot); double ans = 0, fst = sx, lst = sx; for (int i=0;i<tot;i++) { if (s[i].x1 < lst) { ans += (fst-lst) / v1; fst = s[i].x1; lst = s[i].x2; } else { lst = min(lst, s[i].x2); } } ans += (fst - lst) / v1; printf("Case %d: %.4lf\n", cas++, ans); } return 0;}
- HDU4637 Rain on your Fat brother
- HDU 4637 Rain on your Fat brother
- HDU 4637 Rain on your Fat brother
- HDU 4637 Rain on your Fat brother 暑期多校第四场 1009
- hdu 4637 Rain on your Fat brother(几何+区间覆盖)
- HDU 4637 Rain on your Fat brother 线段与半圆和线段交 简单题 (2013多校联合)
- Rain on your Parade
- Rain on your Parade HDU
- Rain on your Parade HDU
- HDU 2389 Rain on your Parade //MAXMATCH
- Hdu 2389 Rain on your Parade
- hdu 2389 Rain on your Parade
- HDU 2389 Rain on your Parade
- hdoj 2389 Rain on your Parade 【HK】
- HDU 2389 Rain on your Parade
- HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade
- hdu2389 Rain on your Parade (最大匹配Hopcroft--Karp)
- hdu_2389 Rain on your Parade 匈牙利算法的bfs实现
- Sybase ASE的字符集
- QT中操作数据库(ACCESS、MySql)
- CCSprite精灵的使用
- android apk签名 增加修改系统时间的权限
- Java中String,StringBuilder和StringBuffer类学习
- HDU4637 Rain on your Fat brother
- 电脑每次开机都要重装USB驱动,或禁用后在启用才能使用?
- hdu1848 Fibonacci again and again (博弈SG值)
- oracle常用的查询语句
- HEVC CU 级别的分析
- 如何获取消息来源的控件ID
- keil c中文件打包成lib文件
- 将项目导入myeclipse后 tortoise svn 右键项目不能更新和提交
- oracle 拼接某个字段的所有值