HDU 5134 Highways (圆与多边形面积交)

Highway

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 285    Accepted Submission(s): 100
Special Judge


Problem Description
You just got your year-end bonus. As you had a lot of money, you decided to take your family to the United States for a twenty-day self-driving travel. One day, when you were driving on the Great Plains, you found you had left highway by accident. After checking your GPS, you realized that you were now D (0 < D <= 1000) miles from the highway. The highway is straight and extends infinitely. When you are driving outside the highway, your maximum speed is v0 mph, but on the highway you can move in a maximum speed of v1 mph (200 >= v1 > 1.2 v0 > 0). It took no time to get on or off the highway. Suddenly, it came to your mind that there was a region inside which any point can be reached within T (0 < T <= 1000) hours. You wanted to know area of this region.
 

Input
Input contains no more than 50 test cases.

Each test case is a single line containing 4 integers v0, v1, D and T, as above mentioned.
 

Output
For each test case, output your answer in a line with the case number, follow the format in sample. Its unit should be square mile. Your answer will be accepted if its absolute or relative error is less than 10-6.

This problem is special judged.
 

Sample Input
  
  
5 10 10 10 5 20 10 10
 

Sample Output
  
  
Case 1: 9360.97707377 Case 2: 14873.82733943
Hint
You should print a blank after ":" in the output.
 

Source
 

Recommend
liuyiding

题解:首先将题目转化为几何问题,就是一个圆和一个六边形的面积交问题,直接套用模板即可
#include <iostream>
#include <bits/stdc++.h>

using namespace std;
double eps=1e-8;
double add(double a,double b)
{
    if(abs(a+b)<eps*abs(a)+abs(b))
        return 0;
    return a+b;
}
double pi=acos(-1);
struct point
{
    double x,y;
    point(){}
    point(double x,double y):x(x),y(y){}
    point operator + (const point p)const
    {
        return point(add(x,p.x),add(y,p.y));
    }
    point operator - (const point p)const
    {
        return point(add(x,-p.x),add(y,-p.y));
    }
    point operator * (const double d)const
    {
        return point(x*d,y*d);
    }
    double dot(point p)
    {
        return add(x*p.x,y*p.y);
    }
};

double d_mult(point a,point b,point c)
{
    return (a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);
}
double x_mult(point a,point b,point c)
{
    return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
double dist(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double  EP=0;
double circlesquare(point a,point b,point c,double r)
{
    double A,B,C,x,y,S;
    A=dist(b,c);
    B=dist(a,c);
    C=dist(a,b);
    if(A<r&&B<r)
        return x_mult(a,b,c)/2;
    else if(A<r&&B>=r)
    {
        x=(d_mult(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;
        S=x_mult(a,b,c)/2;
        return asin(S*(1-x/C)*2/r/B*(1-EP))*r*r/2+S*x/C;
    }
    else if(A>=r&&B<r)
    {
        x=(d_mult(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;
        S=x_mult(a,b,c)/2;
        return asin(S*(1-x/C)*2/r/A*(1-EP))*r*r/2+S*x/C;
    }
    else if(fabs(x_mult(a,b,c))>=r*C||d_mult(b,c,a)<0||d_mult(a,c,b)<0)
    {
        if(d_mult(a,b,c)<0)
            if(x_mult(a,b,c)<0)
                return (-acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-EP)))*r*r/2;
            else
                return (acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-EP)))*r*r/2;
        else
            return asin(x_mult(a,b,c)/A/B*(1-EP))*r*r/2;
    }
    else
    {
        x=(d_mult(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;
        y=(d_mult(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;
        S=x_mult(a,b,c)/2;
        return (asin(S*(1-x/C)*2/r/B*(1-EP))+asin(S*(1-y/C)*2/r/A*(1-EP)))*r*r/2+S*((x+y)/C-1);
    }
}

double v0,v1,d,t;
double fun(double i)
{
    return sqrt((v0 * i) * (v0 * i) - d * d) + v1 * (t - i);
}

int main()
{
    //double v0,v1,d,t;
    int case1=1;
    while(cin>>v0>>v1>>d>>t){
        point cir=point(-d,0);
        double r=v0*t;
        printf("Case %d: ",case1++);
        if(v0*t<=d)
        {
            printf("%.8f\n",pi*r*r);
            continue;
        }
        double l=d/v0,r1=t;
        for(int i=0;i<100;i++)
        {
            double mid=(l+r1)/2;
            double midmid=(mid+r1)/2;
            double _mid=fun(mid);
            double _midmid=fun(midmid);
            if(_mid>_midmid)
                r1=midmid;
            else
                l=mid;
        }
        double t1=(l+r1)/2;
        double y=fun(t1);
        double x1=t/t1*d,y1=sqrt(v0*t*v0*t-x1*x1);
        x1-=d;
        point p[8];
        p[0] = point(0, y);
        p[1] = point(x1, y1);
        p[2] = point(x1, -y1);
        p[3] = point(0, -y);
        p[4] = point(-x1, -y1);
        p[5] = point(-x1, y1);
        //p[6] = p[0];
        double area=0;
        for(int i=0;i<6;i++){
            area+=circlesquare(p[i], p[(i+1)%6], cir, r);
            //cout<<circlesquare(p[i], p[(i+1)%6], cir, r)<<endl;
            //cout<<p[i].x<<' '<<p[i].y<<endl;
        }
        double ans=area;
        ans=pi*r*r+x1*y1*4+x1*(y-y1)*2-fabs(ans);
        //cout << "Hello w<< endl;
        printf("%.8f\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值