码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4793 Collision + HDU 4798 Skycity 简单几何

时间:2014-07-28 15:45:13      阅读:305      评论:0      收藏:0      [点我收藏+]

标签:几何

HDU 4793

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4793 

题意:给一个以(0,0)为圆心半径为R的圆形区域,中间放着一个(0,0)为圆心半径为Rm的圆盘,在坐标(x,y)处(严格在圆形区域外)放着一枚半径为r的硬币,运动方向和速度为(vx,vy),在运动中碰到圆盘时,会按碰撞问题反弹(圆盘是固定不动的),问硬币会在圆形区域里呆多长时间(硬币只要有一点点在圆形区域里就记为硬币在圆形区域内)。

思路:首先先计算出硬币在移动过程中如果不与圆盘相撞,离圆心的最短距离h(如果硬币离圆心越来越远则不可能进入圆形区域)可以用余弦定理或者点到直线距离来求,找到的这个点恰巧是硬币在圆内运行轨迹的中点,如果不与圆盘碰撞,在圆内运行距离就可以用勾股定理求得(勾股弦分别为h,所求距离,圆域半径+硬币半径的直角三角形),如果与圆盘碰撞,那距离就要减去一段距离,也可以用勾股定理求得(勾股弦分别为h,所求距离,圆盘半径+硬币半径的直角三角形),因为硬币在圆域的运行过程是对称的,所以相减得到的距离恰为硬币在圆域内移动距离的一半,即可求得距离,时间。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 100005
#define INF 0x7fffffff
#define eps 1e-8
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int cmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    if(x>0)
        return 1;
    return -1;
}
inline int sgn(double n)
{
    return fabs(n)<eps?0:(n<0?-1:1);
}
inline double sqr(double x)
{
    return x*x;
}
struct point//点
{
    double x,y;
    point() {}
    point(double a,double b):x(a),y(b) {}
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
    friend point operator + (const point &a,const point &b)
    {
        return point(a.x+b.x,a.y+b.y);
    }
    friend point operator - (const point &a,const point &b)
    {
        return point(a.x-b.x,a.y-b.y);
    }
    friend bool operator == (const point &a,const point &b)
    {
        return cmp(a.x-b.x)==0 &&cmp(a.y-b.y)==0;
    }
    friend point operator * (const point &a,const double &b)
    {
        return point(a.x*b,a.y*b);
    }
    friend point operator * (const double &a,const point &b)
    {
        return point(a*b.x,a*b.y);
    }
    friend point operator / (const point &a,const double &b)
    {
        return point(a.x/b,a.y/b);
    }
    double norm()
    {
        return sqrt(sqr(x)+sqr(y));
    }//到原点距离
    void out () const
    {
        printf("%.2f %.2f",x,y);
    }
};
double det (const point &a,const point &b)
{
    return a.x*b.y-a.y*b.x;
}//叉积
double dot (const point &a,const point &b)
{
    return a.x*b.x+a.y*b.y;
}//点乘
double dist (const point &a,const point &b)
{
    return (a-b).norm();
}//距离
point rotate_point(const point &p,double A)
{
    double tx=p.x,ty=p.y;
    return point (tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
}//旋转,A是弧度
struct line
{
    point a,b;
    line() {}
    line(point x,point y):a(x),b(y) {}
    point dire()const
    {
        return b-a;
    }//向量
    double len()
    {
        return dire().norm();
    }
};
bool parallel(line a,line b)
{
    return !cmp(det(a.a-a.b,b.a-b.b));
}
bool line_make_point (line a,line b,point &res)
{
    if(parallel(a,b))
        return false;
    double s1=det(a.a-b.a,b.b-b.a);
    double s2=det(a.b-b.a,b.b-b.a);
    res=(s1*a.b-s2*a.a)/(s1-s2);
    return true;
}
int main()
{
    double Rm,R,r,x,y,vx,vy;
    while(~scanf("%lf%lf%lf%lf%lf%lf%lf",&Rm,&R,&r,&x,&y,&vx,&vy))
    {
        point a=point (x,y);
        point b=point (x-vx,y-vy);
        point e=point (vx,vy);
        line l1=line(a,b);
        point c=point (0,0);
        point d=point (vy,-vx);
        line l2=line(c,d);
        point res;
        line_make_point(l1,l2,res);
        double h=res.norm();
        double h1=R+r;
        double h2=r+Rm;
        double speed=sqrt(vx*vx+vy*vy);
        if(dot(a,e)>=0)
            printf("0.0000\n");
        else if(h>=h1)
            printf("0.0000\n");
        else if(h>=h2)
            printf("%.6lf\n",sqrt(h1*h1-h*h)/speed*2);
        else printf("%.6lf\n",(sqrt(h1*h1-h*h)-sqrt(h2*h2-h*h))/speed*2);
    }
    return 0;
}

HDU 4798

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4798

题意:(真@阅读理解题)给出一个圆台,给出底部半径R和顶部半径r,圆台高度为H,把圆台分成F份登高的小圆台,按每个圆台顶部的圆为标准,用多边形(推得必须是正多边形来保证相切)来围住这些圆,这些多边形都是垂直的帘子,并且给出每个帘子的最小面积S,所以有它们的面积,它们的面积就是它们的耗费。问要求的最小耗费是多少。

思路:所求多边形周长为bubuko.com,布布扣,θ是多边形一个端点和圆心的连线与圆心和这条边中点连线的夹角。θ越大消耗越大,即边数越少,消耗越大。

对于每层,根据最小面积S得到最小边长x,得到可以得到的多边形的边数的最大值,然后算出周长即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define eps 1e-8
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int main()
{
    double R,r,H,S;int F;
    while(~scanf("%lf%lf%lf%d%lf",&R,&r,&H,&F,&S))
    {
        double ans=0;
        double c=(R-r)/F;
        double h=H/F;
        double l=S/h;
        for(int i=0;i<F;i++)
        {
            double rr=r+i*c;
            int tt=(int)(PI/(atan(l/(2*rr))));
            double ss=rr*tan(PI/(1*tt));
            ans+=ss*2*h*tt;
        }
        printf("%.3lf\n",ans);
    }
    return 0;
}



HDU 4793 Collision + HDU 4798 Skycity 简单几何,布布扣,bubuko.com

HDU 4793 Collision + HDU 4798 Skycity 简单几何

标签:几何

原文地址:http://blog.csdn.net/ooooooooe/article/details/38229367

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!