AOJ 2537 Billiard
来源:互联网 发布:sql备份与恢复 编辑:程序博客网 时间:2024/05/18 03:27
Aizu 2537
题意:打台球,已知母球及所有球的半径、位置,求母球打出后第一个碰到的球的编号。
计算几何的模拟。
考虑每个球的中心点,母球中心的运动轨迹只在台的中央,由(r, r), (r, w-r), (h-r, w-r), (h-r, r)四个点组成的矩形内部。
将其设为新的四边,沿着运动方向的射线去和这些边求交点,经过反射后的每个球的坐标可以预处理出来。
模拟至运动距离上限10000即可。
#include <bits/stdc++.h>using namespace std;typedef complex<double> point;typedef point Vec;const int MAXN=15;const double eps=1.0e-9;point cueball, current, previous, nextpos, midpoint, ball[MAXN][2][2];point board[4];struct line : public vector<point> { line() {} line(const point& a, const point& b) { push_back(a); push_back(b); }};struct Circle{ point center; double radius; Circle(const point& c, const double& r):center(c),radius(r) {}};point unit(const point& v) { return v/abs(v);}inline double dot (const point& a, const point& b) { return (a*conj(b)).real();}inline double cross(const point& a, const point& b) { return (conj(a)*b).imag();}inline point vec(const line& l) { return l[1]-l[0];}bool intersectSP(const line& s, const point& p) { return abs(s[0]-p)+abs(s[1]-p) < abs(s[1]-s[0])+eps;}point crosspoint(const line& l, const line& m) { ///use Intersection Judging first double A = cross(vec(l), vec(m)); double B = cross(vec(l), l[1]-m[0]); if(abs(A)<eps) { // parallel return m[0]; // sameline } return m[0] + B/A*vec(m);}point intersection_point(const line& A, const Circle& C){ double dx=real(A[1]-A[0]), dy=imag(A[1]-A[0]); double rx=real(A[0]-C.center), ry=imag(A[0]-C.center); double a=dx*dx+dy*dy, b=2*dx*rx+2*dy*ry, c=rx*rx+ry*ry-C.radius*C.radius; double delta=b*b-4*a*c; if(delta<-eps) return point(-100000,-100000); delta=max(0.0,delta); double ans=(-b-sqrt(delta))/(2.0*a); if(ans>=0) return point(A[0].real()+ans*dx,A[0].imag()+ans*dy); ans=(-b+sqrt(delta))/(2.0*a); if(ans>=0) return point(A[0].real()+ans*dx,A[0].imag()+ans*dy); return point(-100000,-100000);}int main(){ int n, w, h, r, v_x, v_y; Vec direction; while(cin>>n&&n){ cin>>w>>h>>r>>v_x>>v_y; w-=r*2, h-=r*2; direction=point(v_x,v_y); direction=unit(direction); for(int i=0, x, y; i<n; i++){ scanf("%d%d",&x,&y); x-=r; y-=r; if(i==0) cueball=point(x,y); else ball[i-1][0][0]=point(x,y); } n--; point tmp; for(int i=0; i<n; i++){ tmp=ball[i][0][0]; double x=tmp.real(), y=tmp.imag(); ball[i][0][1]=point(x,h-y); ball[i][1][0]=point(w-x,y); ball[i][1][1]=point(w-x,h-y); } double dist=0; int ans=-1; int nowx=0, nowy=0, nextx=0, nexty=0; current=cueball; while(dist<=10000){ previous=current; nowx=nextx; nowy=nexty; board[0]=point(nowx*w,nowy*h); board[1]=point((nowx+1)*w,nowy*h); board[2]=point((nowx+1)*w,(nowy+1)*h); board[3]=point(nowx*w,(nowy+1)*h); double ret=0; for(int i=0; i<4; i++){ tmp=crosspoint(line(board[i], board[(i+1)%4]), line(previous, previous+direction)); if(intersectSP(line(board[i], board[(i+1)%4]), tmp) && dot(previous-tmp, previous+100000.0*direction-tmp)<0 && abs(tmp-previous)>ret){ ret=abs(tmp-previous); current=tmp; } } midpoint=current+direction; nextx=floor(midpoint.real()/w); nexty=floor(midpoint.imag()/h); double ansdist=1.0e20; for(int i=0; i<n; i++){ tmp=ball[i][nowx&1][nowy&1]+point(nowx*w,nowy*h); point intersect=intersection_point(line(previous,current),Circle(tmp,2*r)); if(intersect!=point(-100000,-100000)){ double ndist=abs(intersect-previous); if(ndist<ansdist&&dist+ndist<=10000){ ansdist=ndist; ans=i+2; } } } if(ans!=-1){ break; } dist+=ret; } printf("%d\n",ans); } return 0;}
0 0
- AOJ 2537 Billiard
- Billiard
- AOJ
- Aoj
- 10387 - Billiard
- 10387 - Billiard
- 10387 - Billiard
- 10387 - Billiard
- Billiard uva
- UVA10387 Billiard
- uva 10387 - Billiard
- uva-10387 - Billiard
- UVa 10387 - Billiard
- UVa 10387 - Billiard
- UVA 10387 - Billiard
- uva 10387 - Billiard
- uva-10387 - Billiard
- uva 10387 - Billiard
- C++类的继承笔记
- Java: Special Point about Name o…
- Java: Keyword final
- mysqld的安装和基本增删改查
- cnn下matlab移植opencv体会
- AOJ 2537 Billiard
- Java: Instance Initialization
- Java: A Puzzle about Constructor…
- Linux学习笔记-----挂载到底是什么意思???本质是什么???
- 给JFinal添加Shiro插件功能,支持Shiro所有注解-使用篇
- java摄像头实时摄像程序
- Java: Snack from Constructor
- Unity3D研究院之Assetbundle的原理(六十一)
- Java: Exception Trace Kick off