标签:几何
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; }
链接: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 简单几何,布布扣,bubuko.com
HDU 4793 Collision + HDU 4798 Skycity 简单几何
标签:几何
原文地址:http://blog.csdn.net/ooooooooe/article/details/38229367