思路:把球体方程和直线方程联立解出来交点的值作为区间,那么就变成最多区间覆盖的问题了
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define LL __int64
const int maxn = 1000005;
struct Node
{
double s,t;
}nodes[maxn];
bool cmp(Node a,Node b)
{
if (a.t<b.t)
return true;
else
return false;
// return a.t<b.t;
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
LL n,r;
scanf("%I64d%I64d",&n,&r);
LL pos=0;
LL x,y,z,dx,dy,dz;
LL ans = 0;
for (LL i = 0;i<n;i++)
{
scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&x,&y,&z,&dx,&dy,&dz);
LL a = dx*dx+dy*dy+dz*dz;
LL b = 2*(dx*x+dy*y+dz*z);
LL c = x*x+y*y+z*z-r*r;
LL delta = b*b-4*a*c;
if (delta>=0)
{
double s = (-b+sqrt(delta*1.0)) / (2.0*a);
double t = (-b-sqrt(delta*1.0)) / (2.0*a);
if (s>t)
swap(s,t);
if (t>=0)
{
if (s<0)
s=0;
nodes[pos].s=s;
nodes[pos].t=t;
pos++;
}
}
}
sort(nodes,nodes+pos,cmp);
//LL ans = 0;
double temp=-1;
for (LL i = 0;i<pos;i++)
{
if (nodes[i].s>temp)
{
temp = nodes[i].t;
ans++;
}
}
printf("Case %d: %I64d %I64d\n",cas++,pos,ans);
}
}