题意

给定一个边长为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;
}