题意
给定一个边长为L的三角形和一个直径非常微小的球,问球在三角形内与三角形的边第k次碰撞的时间
思路
模型转化:将碰撞转化为穿越
二分查找时间
code:
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-7;
#define endl "\n"
#define int long long
struct Point{
long double x,y;
Point operator+(const Point &a) const {return {x+a.x,y+a.y};}
Point operator-(const Point &a) const {return {x-a.x,y-a.y};}
Point operator-() const {return {-x,-y};}
Point operator*(const double k) const {return {k*x,k*y};}
Point operator/(const double k) const {return {x/k,y/k};}
double operator*(const Point &a) const {return x*a.x+y*a.y;} //Dot
double operator^(const Point &a) const {return x*a.y-y*a.x;} //Cross
};
struct Line{
Point p,v;
};
int L,k,x,y,vx,vy;
const long double sq3=sqrtl(3);
int _ceil(const double &x)
{
long long k=ceil(x);
while (k<x) k++;
while (k>x+1) k--;
return k;
}
int check(long double t){
int res=0;
Point lst={vx*t+x,vy*t+y};
const long double c=sqrtl(3)*L;
int k1=_ceil((lst.y+sq3*lst.x-c/2)/c);
k1=abs(k1);
int k2=_ceil((lst.y-sq3*lst.x-c/2)/c);
k2=abs(k2);
int k3=ceil(lst.y/(c/2));
k3=abs(k3-1);
return k1+k2+k3;
}
void sol(){
cin>>L>>x>>y>>vx>>vy>>k;
double l=0,r=1e15;
long double ans;
while(r-l>eps){
long double mid=(l+r)/2;
int cnt=check(mid);
if(cnt>=k){
r=mid;
ans=mid;
}
else l=mid;
}
printf("%.6Lf\n",ans);
}
signed main(){
int t;
cin>>t;
while(t--){
sol();
}
return 0;
}
标签:二分,const,Point,int,double,long,return,Triangle,Cillision
From: https://www.cnblogs.com/muyi-meow/p/18155227