有 \(n\) 个雪球,每个雪球用 \(6\) 个整数 \(x_i,y_i,z_i,u_i,v_i,w_i\) 表述,代表雪球 \(i\) 在 \(t\) 时刻的位置是 \((x_i+u_it,y_i+v_it,z_i+w_it)\)。
\(\texttt{Part 1 : }\)在只考虑 \(xy\) 平面的情况下,有多少对雪球的轨迹会在某一个特定的方形区间内相交?
\(\texttt{Part 2 : }\)现在有一个魔法雪球,它在与每一个雪球在 整数时间刻 时相遇。问这个雪球的坐标之和是多少,保证只有唯一解。
\(\texttt{Constaints : }n\le 300\).
直接枚举每一对雪球,通过代数计算交点判断即可。
import sys
import recr=lambda a1,b1,c1,d1,a2,b2,c2,d2: (d2*a2+c2*b1-c2*b2-d2*a1)/(d2*c1-c2*d1) if d2*c1-c2*d1!=0 else 1e18
val=lambda k1,b1,x: b1+k1*x
fit=lambda l,r,x: x>=l and x<=ra=open(0).readlines()
l,r=map(int,a[0].split(' '))
a=list(map(lambda it:re.findall("[0-9-]+",it),a[1:]))
a=list(map(lambda it:list(map(int,it)),a))tar=0for i in range(len(a)):for j in range(i+1,len(a)):s=cr(a[i][0],a[i][1],a[i][3],a[i][4],a[j][0],a[j][1],a[j][3],a[j][4])t=cr(a[j][0],a[j][1],a[j][3],a[j][4],a[i][0],a[i][1],a[i][3],a[i][4])if s<0 or t<0 : continueif fit(l,r,val(a[i][3],a[i][0],s)) and fit(l,r,val(a[i][4],a[i][1],s)):tar+=1
print(tar)
我们发现坐标很难直接求出,所以我们考虑先求速度。
假设我们先求 \(u_0\)。
我们发现,对于两个拥有相同 \(u_i\) 值的两个雪球,在以他们为参考系的情况下,只有魔法雪球会动。
设他们的 \(x\) 坐标为 \(x_i\),\(x_j\),那么由于魔法雪球与他们只在整数时间刻时相遇,所以相遇的时间差也是整数。
即 \(\Large\frac{x_i-x_0}{u_i-u_0}-\frac{x_j-x_0}{u_i-u_0}=\frac{x_i-x_j}{u_i-u_0}\) 是整数。
即:
那么我们就拥有了一堆同余的方程需要满足。
大胆假设速度必然不会很大,所以在 \([-5000,5000]\) 中暴力试数即可。
同理,\(v_0\) 与 \(w_0\) 也可以求出。
现在,我们求出速度以后,以魔法雪球为参考系。由于所有雪球都与它相遇,所以此时 所有雪球的轨迹相交于一点。
判断所有雪球的轨迹是否相交于一点后焦点就是答案。
import sys
import redef equ(x,y):return x==y or x==-1e18 or y==-1e18def calc(x):tx=[]for it in range(-5000,5000):flag=Truefor (l,vx) in x:if it==vx or l%(it-vx):flag=Falseif flag: tx.append(it)return txa=list(map(lambda it:re.findall(r"[\d-]+",it),open(0).readlines()))
a=list(map(lambda it:list(map(int,it)),a))x,y,z,tar=[],[],[],[]for i in range(len(a)):for j in range(i+1,len(a)):if a[i][3]==a[j][3]:x.append((abs(a[i][0]-a[j][0]),a[i][3]))if a[i][4]==a[j][4]:y.append((abs(a[i][1]-a[j][1]),a[i][4]))if a[i][5]==a[j][5]:z.append((abs(a[i][2]-a[j][2]),a[i][5]))
tx,ty,tz=calc(x),calc(y),calc(z)for vx in tx:for vy in ty:for vz in tz:la,lb=a[0],a[1]x0,y0,z0,u0,v0,w0=la[0],la[1],la[2],la[3]-vx,la[4]-vy,la[5]-vzx1,y1,z1,u1,v1,w1=lb[0],lb[1],lb[2],lb[3]-vx,lb[4]-vy,lb[5]-vzt1=(u1*y0-u1*y1-v1*x0+v1*x1)/(v1*u0-v0*u1)t2=(x0-x1+u0*t1)/u1if t1<0 or t2<0: continueres=(x0+u0*t1,y0+v0*t1,z0+w0*t1)if int(res[0])!=res[0] or int(res[1])!=res[1] or int(res[2])!=res[2]:continueflag=Truefor (x2,y2,z2,u2,v2,w2) in a:tt1=(res[0]-x2)/(u2-vx) if u2!=vx else (-1e18 if res[0]==x2 else 1e18+vx)tt2=(res[1]-y2)/(v2-vy) if v2!=vy else (-1e18 if res[1]==y2 else 1e18+vy)tt3=(res[2]-z2)/(w2-vz) if w2!=vz else (-1e18 if res[2]==z2 else 1e18+vz)flag&=(equ(tt1,tt2) and equ(tt2,tt3) and equ(tt1,tt3))if not flag: continuetar.append(((int(res[0]),int(res[1]),int(res[2])),(vx,vy,vz),int(sum(res))))
print('\n'.join(map(lambda it:str(it)[1:-1],tar)))