HDU 4637 Rain on your Fat brother
来源:互联网 发布:c二维数组初始化为0 编辑:程序博客网 时间:2024/05/29 08:43
题意可以归纳为:求一条线段和雨滴的交的总长度。
分析:雨滴和线段的交点可以分为三角形和半圆的交点,注意线段可能会重复, 扫描线判重就可以了。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <string>#include <cstring>#include <vector>#define FOR(i, n) for(int i = 0; i < n; i++)#define MEM(array) memset(array, 0, sizeof(array))#define eps 1e-7#define INF 1e10#define PI acos(-1.0)using namespace std;inline int sgn(const double &x){return x > eps ? 1 : (x < -eps ? -1 : 0);}inline double sqr(const double &x){return x * x;}struct Point{ double x, y; Point(){} Point(const double &xx, const double &yy):x(xx), y(yy){} Point operator + (const Point &a)const { return Point(x + a.x, y + a.y); } Point operator - (const Point &a)const { return Point(x - a.x, y - a.y); } Point operator * (const double &w)const{ return Point(x * w, y * w); } Point operator / (const double &w)const{ return Point(x / w, y / w); } friend Point operator * (const double &w, const Point &a){ return Point(a.x * w, a.y * w); } friend double det(const Point &a, const Point &b){ return a.x * b.y - a.y * b.x; } friend double dot(const Point &a, const Point &b){ return a.x * b.x + a.y * b.y; } friend double dist(const Point &a, const Point &b){ return (b - a).len(); } double len()const{ return sqrt( dot(*this, *this)); } Point norm()const{ double vLen = len(); return Point(x / vLen , y / vLen); } Point rotate(double angle){ double x1 = x * cos(angle) - y * sin(angle); double y1 = x * sin(angle) + y * cos(angle); return Point(x1, y1); } bool operator < (const Point &a)const { return sgn(x - a.x) < 0 || (sgn(x - a.x) == 0 && sgn(y - a.y) > 0); } bool operator > (const Point &a)const { return sgn(x - a.x) > 0 || (sgn(x - a.x) == 0 && sgn(y - a.y) < 0); } bool operator == (const Point &a)const { return sgn(x - a.x) == 0 && sgn(y - a.y) == 0; } void in(){ scanf("%lf %lf", &x, &y); } void out()const{ printf("%.4f %.4f\n", x, y); }};struct Line{ Point s, t; Line(){} Line(const Point &ss, const Point &tt):s(ss), t(tt){} friend bool lineParallelLine(const Line &l1, const Line &l2){ return sgn(det(l1.t - l1.s, l2.t - l2.s)) == 0; } friend bool isPointOnLine(const Point &a, const Line &line){ Point va = line.s - a, vb = line.t - a; int res1 = sgn(det(va, vb)); if(res1 != 0)return false; return sgn( dot(va, vb) ) <= 0; } friend double pointDistLine(const Point &p, const Line &line){ return fabs(det(p - line.s, line.t - line.s)/ (line.t- line.s).len()); } friend Point pointProjLine(const Point &p, const Line &line){ return line.s + ( line.norm() * dot(p - line.s, line.t - line.s)/ (line.t - line.s).len() ); } friend bool sameSide(const Line &line, const Point &a, const Point &b){ int res1 = sgn(det( a - line.s, line.t - line.s)); int res2 = sgn(det( b - line.s, line.t - line.s)); return res1 * res2 > 0; } friend vector<Point> lineInsectLine(const Line &l1, const Line &l2){ vector<Point>res; if(lineParallelLine(l1, l2)){ if( sgn(pointDistLine(l1.s, l2))==0 )res.push_back(l1.s); if( sgn(pointDistLine(l1.t, l2))==0 )res.push_back(l1.t); }else { Point vs = l1.s - l2.s, vl = l2.t - l2.s, vt = l1.t - l2.s; double s1 = det(vs, vl), s2 = det(vt, vl); res.push_back( (s1 * l1.t - s2 * l1.s)/(s1- s2)); } return res; } Point norm()const{ return (t - s).norm(); } Point vec()const{ return t - s; } void out()const{ s.out(); t.out(); }};int numl;struct Tri{ Point a[3]; Tri(){} Tri(const Point &aa, const Point &bb, const Point &cc){ a[0] = aa; a[1] = bb; a[2] = cc; } friend vector<Point> triInsectLine(const Tri &tri, const Line &line){ vector<Point>res, tt; for(int i = 0; i < 3; i++){ Line linet(tri.a[i], tri.a[(i + 1)%3]); tt = lineInsectLine(line, linet); FOR(j, tt.size()){ if(isPointOnLine(tt[j], linet))res.push_back(tt[j]); } } sort(res.begin(), res.end()); int tn = unique(res.begin(), res.end()) - res.begin(); res.resize(tn); return res; }};struct Cir{ Point o; double r; Cir(){} Cir(const Point &p, const double &rr):o(p), r(rr){} friend vector<Point> cirInsectLine(const Cir &cir, const Line &line){ vector<Point>res; double dist = pointDistLine(cir.o, line); if(dist < cir.r){ double len = sqrt(sqr(cir.r) - sqr(dist)); Point re = pointProjLine(cir.o, line); Point tt1 = re - (line.norm() * len), tt2 = re + (line.norm() * len); if( sgn(tt1.y - cir.o.y) < 0) res.push_back(tt1); if( sgn(tt2.y - cir.o.y) < 0) res.push_back(tt2); } return res; } void in(){ o.in(); scanf("%lf",&r); }};Point endPoint, srcPoint;Line mainLine, endLine;struct Rain{ Tri tri; Cir cir; Rain(){} friend Line rainInsectLine(const Rain &rain, const Line &line){ vector <Point>res; vector<Point>res1 = triInsectLine(rain.tri, line); vector<Point>res2 = cirInsectLine(rain.cir, line); Point leftPoint = line.t, rightPoint = line.s; FOR(i, res1.size()){ res.push_back(res1[i]); } FOR(i, res2.size()){ res.push_back(res2[i]); } int len = res.size(); if(len > 1){ FOR(i, len){ if(leftPoint > res[i])leftPoint = res[i]; if(rightPoint < res[i])rightPoint = res[i]; } if(leftPoint < line.s)leftPoint = line.s; if(rightPoint > line.t)rightPoint = line.t; }else { leftPoint = rightPoint; } return Line(leftPoint, rightPoint); } void in(){ cir.in(); double h; scanf("%lf", &h); Point a(cir.o.x - cir.r, cir.o.y), b(cir.o.x + cir.r, cir.o.y), c(cir.o.x, cir.o.y + h); tri = Tri(a, b, c); }}rain[11111];double va, vb, vr, t, x;int n;Point vMain;void init(){ srcPoint = Point(x, 0); t += t *va/ (vb - va); vMain = Point(-va, vr); endPoint = srcPoint + vMain * t; mainLine = Line(endPoint, srcPoint);}struct pointR{ Point p; int type; bool operator < (const pointR &a)const { return p < a.p; }}pr[11111];int ca = 0;double ans = 0;void solve(){ ans = 0; FOR(i, n){ Line line = rainInsectLine(rain[i], mainLine); pr[i * 2].p = line.s; pr[i * 2].type = 1; pr[i * 2 + 1].p = line.t; pr[i * 2 + 1].type = -1; } int cnt = 0; sort(pr, pr + 2 * n); FOR(i, 2 * n){ if(cnt){ ans += fabs( Line(pr[i -1].p, pr[i].p).vec().len()); } cnt += pr[i].type; } printf("Case %d: %.4f\n", ++ca, ans / vMain.len());}int main(){ int T; scanf("%d", &T); while(T--){ scanf("%lf %lf %lf %lf %lf", &va, &vb, &vr, &t, &x); scanf("%d", &n); FOR(i, n){ rain[i].in(); } init(); solve(); } return 0;}/*211 2 1 5 01-4 5 2 2*/
- HDU 4637 Rain on your Fat brother
- HDU 4637 Rain on your Fat brother
- HDU4637 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 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
- HDU 2389 Rain on your Parade
- HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade
- Rain on your Parade
- HDU 2389 Rain on your Parade(HK||KM,4级)
- hdu 2389 Rain on your Parade 二分匹配 HK算法
- 【二分匹配】 HDU 2389 Rain on your Parade HK算法
- 黑马程序员--多线程
- strcat可用版
- 全排序vs八皇后问题vs三角八皇后
- Objective-c的第一个问题:中缀符,到底什么是函数名,什么是参数?
- 我对互联网营销时代的发展认知
- HDU 4637 Rain on your Fat brother
- EMACS下 弹出窗口式的 Auto-Complete 自动补全工具简单介绍
- adb server is out of date. killing...
- iOS的主要框架介绍
- KBuild MakeFile介绍
- POJ 1308 Is It A Tree?
- C语言信号量的基本操作
- /* HDU 1232 */
- double变量的C++ 输出时的小数点后的位数控制