HDU 4793 Collision + HDU 4798 Skycity 简单几何

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,所以有它们的面积,它们的面积就是它们的耗费。问要求的最小耗费是多少。

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

对于每层,根据最小面积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 简单几何

时间: 2024-12-14 07:29:14

HDU 4793 Collision + HDU 4798 Skycity 简单几何的相关文章

HDU 4793 Collision (2013长沙现场赛,简单计算几何)

Collision Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 685    Accepted Submission(s): 248Special Judge Problem Description There's a round medal fixed on an ideal smooth table, Fancy is tryin

HDU 4793 Collision(2013长沙区域赛现场赛C题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4793 解题报告:在一个平面上有一个圆形medal,半径为Rm,圆心为(0,0),同时有一个圆形范围圆心也是(0,0),半径为R,R > Rm,现在向平面上投掷一枚硬币,硬币初始的圆心位置为(x,y),半径是r,给出硬币的速度向量,硬币碰到medal的时候会反射,注意,反射就是原路返回,并不是按照常理的按照圆心连线的路线,表示一直以为是这样,WA了很久,然后,让你求硬币跟圆形范围有交集的时候的总时间是

HDU 5218 The E-pang Palace (简单几何—2014广州现场赛)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5128 题面: The E-pang Palace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 1646    Accepted Submission(s): 1226 Problem Description E-pang Palac

HDU 4793 Collision --解方程

题意: 给一个圆盘,圆心为(0,0),半径为Rm, 然后给一个圆形区域,圆心同此圆盘,半径为R(R>Rm),一枚硬币(圆形),圆心为(x,y),半径为r,一定在圆形区域外面,速度向量为(vx,vy),硬币向圆盘撞过去,碰到圆盘后会以相反方向相同速度回来(好像有点违背物理规律啊,但是题目是这样,没办法).问硬币某一部分在圆形区域内的总时间. 解法: 解方程,求 (x+vx*t,y+vy*t) 代入圆形区域方程是否有解,如果没解,说明硬币运动轨迹与圆形区域都不相交,答案为0 如果有解,再看代入圆盘有

HDU 1038[Biker&#39;s Trip Odometer]简单计算

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1038 题目大意:给轮子直径,转数,时间.要求输出走过的距离和时速(mile为单位) 关键思想:纯算 代码如下: #include <iostream> using namespace std; #define pi 3.1415927 int main(){ double d,r,t,l; int cnt=1; while(cin>>d>>r>>t&&a

[HDU 4082] Hou Yi&#39;s secret (简单计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4082 题目大意: 给你n个点,问能最多构成多少个相似三角形. 用余弦定理,计算三个角度,然后暴力数有多少个,更新答案. 代码: 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #includ

hdu 1201 18岁生日 (简单题)

18岁生日 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18281    Accepted Submission(s): 5776 Problem Description Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他

HDU 1715 大菲波数(JAVA, 简单题,大数)

题目 //BigInteger 和 BigDecimal 是在java.math包中已有的类,前者表示整数,后者表示浮点数 import java.io.*; import java.util.*; import java.math.*; public class Main { /** * @xqq */ public BigInteger an(BigInteger a, BigInteger b, int n) { if(n == 1) { return a; } for(int i = 2

?HDU 5795 A Simple Nim(简单Nim)

HDU 5795 A Simple Nim(简单Nim) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On e