标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1430 Accepted Submission(s): 270
题意:有一个质点位于点(x,y),初速度为(vx,vy),有一个柱子位于(ox,oy)半径为r,假设质点碰到柱子后发生弹性碰撞,问是否质点能经过(bx,by)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
#include <bitset>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define CT continue
#define SC scanf
const double eps=1e-8;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x>0?1:-1;
}
struct Point {
double x,y;
void read()
{
SC("%lf%lf",&x,&y);
}
};
struct circle{
Point o;
int r;
void read()
{
SC("%lf%lf%d",&o.x,&o.y,&r);
}
};
Point operator-(Point a,Point b)
{
return (Point){a.x-b.x,a.y-b.y};
}
Point operator+(Point a,Point b)
{
return (Point){a.x+b.x,a.y+b.y};
}
Point operator*(double p,Point a)
{
return (Point){a.x*p,a.y*p};
}
double dot(Point a,Point b)
{
return a.x*b.x+a.y*b.y;
}
double dis(Point a)
{
return sqrt(dot(a,a));
}
double cross(Point a,Point b)
{
return a.x*b.y-b.x*a.y;
}
Point GetLineProjection(Point P,Point A,Point B)
{
Point v=B-A;
Point ans=A+(dot(v,P-A)/dot(v,v))*v;
return ans;
}
Point jiaoa,jiaob,tou;double d;
void getjiaopoint(Point pa,Point pav,circle C)
{
Point A=pa,B=pa+pav;
if(dis(C.o-B)>dis(C.o-A)){
A=pa+pav;
B=pa;
}
tou=GetLineProjection(C.o,A,B);
d=dis(tou-C.o);
if(dcmp(d-C.r)<0)
{
double l=sqrt((double)C.r*C.r-d*d);
jiaoa=tou+l/dis(B-A)*(B-A);
jiaob=tou-l/dis(B-A)*(B-A);
}
}
int main()
{
int cas;SC("%d",&cas);
circle C;
int kk=0;
Point pa,pb,pav;
while(cas--)
{
C.read();
pa.read();pav.read();pb.read();
getjiaopoint(pa,pav,C);
if(dcmp(d-C.r)>=0)
{
if(dcmp(cross(pb-pa,pav))==0&&dcmp(dot(pb-pa,pav))>0)
printf("Case #%d: Yes\n",++kk);
else printf("Case #%d: No\n",++kk);
CT;
}
Point chap;
if(dcmp(dis(jiaoa-pa)-dis(jiaob-pa))<0) chap=jiaoa;
else chap=jiaob;
int flag=0;
if(dcmp(cross(pa-pb,chap-pb))==0&&dcmp(dot(pa-pb,chap-pb))<=0)
flag=1;
Point I=GetLineProjection(pa,C.o,chap);
Point pa2=pa+2*(I-pa),pa2v=chap-pa2;
if(dcmp(cross(pb-chap,pa2v))==0&&dcmp(dot(pb-chap,pa2v))<=0)
flag=1;
if(flag) printf("Case #%d: Yes\n",++kk);
else printf("Case #%d: No\n",++kk);
}
return 0;
}
分析:
1.直接根据向量求出角度再比大小容易错(精度),可做a点关于直线的对称点a2,再判断b点是否在chap与a2该条射线上
pa
hdu 5572 An Easy Physics Problem 圆+直线
标签:
原文地址:http://www.cnblogs.com/smilesundream/p/5930481.html