HDOJ 5134 Highway

来源:互联网 发布:厦门房叔快修网络 编辑:程序博客网 时间:2024/05/29 04:56
#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 1005#define maxm 2000005#define eps 1e-10#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R#define pii pair<int, int>//#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}// headint sgn(double x){    if(fabs(x) < eps) return 0;    if(x < 0) return -1;    else return 1;}struct Point{    double x, y;    Point() {}    Point(double _x, double _y) {        x = _x;        y = _y;    }    bool operator == (Point b) const {        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;    }    bool operator < (Point b) const {        return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;    }    Point operator - (const Point &b) const {        return Point(x - b.x, y - b.y);    }    double operator ^ (const Point &b) const {        return x * b.y - y * b.x;    }    double operator * (const Point &b) const {        return x * b.x + y * b.y;    }    double len(void)    {        return hypot(x, y);    }    double len2(void)    {        return x * x + y * y;    }    double distance(Point p)    {        return hypot(x - p.x, y - p.y);    }    Point operator + (const Point &b) const {        return Point(x + b.x, y + b.y);    }    Point operator * (const double &k) const {        return Point(x * k, y * k);    }    Point operator / (const double &k) const {        return Point(x / k, y / k);    }    double rad(Point a, Point b) {        Point p = *this;        return fabs(atan2(fabs((a - p) ^ (b - p)), (a - p) * (b - p)));    }    Point trunc(double r) {        double l = len();        if(!sgn(l)) return *this;        r /= l;        return Point(x * r, y * r);    }    void input(void)    {        scanf("%lf%lf", &x, &y);    }    Point rotleft(void)    {        return Point(-y, x);    }    Point rotright(void)    {        return Point(y, -x);    }};struct Line{    Point s, e;    Line() {}    Line(Point _s, Point _e) {        s = _s;        e = _e;    }    double length(void)    {        return s.distance(e);    }    Point lineprog(Point p) {        return s + (((e - s) * ((e - s) * (p - s))) / ((e - s).len2()));    }    double dispointtoline(Point p)    {        return fabs((p - s) ^ (e - s)) / length();    }};struct circle{    Point p;    double r;    circle() {}    circle(Point _p, double _r) {        p = _p;        r = _r;    }    circle(double x, double y, double _r) {        p = Point(x, y);        r = _r;    }    int relation(Point b)    {        double dst = b.distance(p);        if(sgn(dst - r) < 0) return 2;        else if(sgn(dst - r) == 0) return 1;        return 0;    }    int relationline(Line v)    {        double dst = v.dispointtoline(p);        if(sgn(dst - r) < 0) return 2;        else if(sgn(dst - r) == 0) return 1;        return 0;    }        int pointcrossline(Line v, Point &p1, Point &p2)    {        if(!(*this).relationline(v)) return 0;        Point a = v.lineprog(p);        double d = v.dispointtoline(p);        d = sqrt(r *r - d * d);        if(sgn(d) == 0) {            p1 = a;            p2 = a;            return 1;        }        p1 = a + (v.e - v.s).trunc(d);        p2 = a - (v.e - v.s).trunc(d);        return 2;    }    double areatriangle(Point a, Point b)    {        if(sgn((p - a) ^ (p - b)) == 0) return 0.0;        Point q[5];        int len = 0;        q[len++] = a;        Line l(a, b);        Point p1, p2;        if(pointcrossline(l, q[1], q[2]) == 2) {            if(sgn((a - q[1]) * (b - q[1])) < 0) q[len++] = q[1];            if(sgn((a - q[2]) * (b - q[2])) < 0) q[len++] = q[2];        }        q[len++] = b;        if(len == 4 && sgn((q[0] - q[1]) * (q[2] - q[1])) > 0) swap(q[1], q[2]);        double res = 0;        for(int i = 0; i < len-1; i++) {            if(relation(q[i]) == 0 || relation(q[i+1]) == 0) {                double arg = p.rad(q[i], q[i+1]);                res += r * r * arg / 2.0;            }            else {                res += fabs((q[i] - p) ^ (q[i+1] - p)) / 2.0;            }        }        return res;    }    int tangentline(Point q, Line &u, Line &v) {        int x = relation(q);        if(x == 2) return 0;        if(x == 1) {            u = Line(q, q + (q - p).rotleft());            v = u;            return 1;        }        double d = p.distance(q);        double l = r * r / d;        double h = sqrt(r *r - l * l);        u = Line(q, p + ((q - p).trunc(l) + (q - p).rotleft().trunc(h)));        v = Line(q, p + ((q - p).trunc(l) + (q - p).rotright().trunc(h)));        return 2;    }};struct polygon{    int n;    Point p[maxn];    Line l[maxn];    void input(int _n)    {        n = _n;        for(int i = 0; i < n;  i++)            p[i].input();    }    void getline(void)    {        for(int i = 0; i < n; i++)            l[i] = Line(p[i], p[(i+1) % n]);    }    double areacircle(circle c)    {        double ans = 0;        for(int i = 0; i < n; i++) {            int j = (i + 1) % n;            if(sgn((p[j] - c.p) ^ (p[i] - c.p)) >= 0)                ans += c.areatriangle(p[i], p[j]);            else ans -= c.areatriangle(p[i], p[j]);        }        return fabs(ans);    }    double getarea(void)    {        double sum = 0;        for(int i = 0; i < n; i++) {            sum += (p[i] ^ p[(i+1) % n]);        }        return fabs(sum) / 2;    }};polygon poly;circle c;double v0, v1, d, t;Point pp;circle test;Line u, v;double mx;double calc(double x){    double t2 = t - sqrt(d * d + x * x) / v0;    return t2 * v1 + x;}double find(void){    double bot = 0, top = v1 * t, mid1, mid2;    while(top - bot > eps) {        mid1 = bot + (top - bot) / 3;        mid2 = bot + (top - bot) / 3 * 2;        if(calc(mid1) > calc(mid2)) top = mid2;        else bot = mid1;    }    return mid1;}void work(void){    double ans = PI * (v0 * t) * (v0 * t);    if(sgn(v0 * t - d) <= 0) {        printf("%.9f\n", ans);        return;    }    c = circle(Point(0.0, 0.0), v0 * t);    double pos = find();    double mx = calc(pos);    test = circle(Point(pos, d), (t - sqrt(d * d + pos * pos) / v0) * v0);    pp = Point(mx, d);    int temp = test.tangentline(pp, u, v);    double tmp = mx * abs(u.e.y - u.s.y) / abs(u.e.x - u.s.x);    poly.p[0] = u.e;    poly.p[1] = Point(mx, d);    poly.p[2] = v.e;    poly.n = 3;    poly.getline();    ans += 2 * poly.getarea();    ans -= 2 * poly.areacircle(c);    printf("%.9f\n", ans);}int main(void){    int _ = 0;    while(scanf("%lf%lf%lf%lf", &v0, &v1, &d, &t)!=EOF) {        printf("Case %d: ", ++_);        work();    }    return 0;}

0 0
原创粉丝点击