吐槽一句,这题是绿的就离谱。
题意
给一条直线的斜率 (a) 和截距 (b) ,和某一时刻 (n) 个在直线上的点的横坐标,还有每个点沿坐标轴的速度 (v_x,v_y) 。
问这些点在 ((-infty,+infty)) 的时间内的碰撞次数。
Solution
设某两个点在时间 (t) 发生了碰撞,则有:
[x_1+v_{x1}t=x_2+v_{x2}t\y_1+v_{y1}t=y_2+v_{y2}t
]
移项+消去 (t) ,可得:
[dfrac {x_1-x_2}{v_{x2}-v_{x1}}=frac {y_1-y_2}{v_{y2}-v_{y1}}
]
又由某个斜率的表达式 (k=frac {y_1-y_2}{x_1-x_2}) ,得到:
[frac {v_{y2}-v_{y1}}{v_{x2}-v_{x1}}=aRightarrow v_{y2}-v_{y1}=a imes (v_{x2}-v_{x1})
]
再次移项,可以得到:
[v_{y2}-a imes v_{x2}=v_{y1}-a imes v_{x1}
]
也就是当两个点满足这个条件时,就会在某个时间发生碰撞。
所以可以开一个 (map) 记录 (v_y-a imes v_x) 的数量。但是还有些点,它们的 (v_x,v_y) 如果相同,是保持相对静止的,所以还要开一个 (map) 记录这些点,计算的时候减去。
代码
#include<bits/stdc++.h>
#define ll long long
#define PLL pair<ll,ll>
using namespace std;
ll a,b,n,ans;
map<ll,int> mp;
map<PLL,int> same;
int main(){
scanf("%lld%lld%lld",&n,&a,&b);
for(int i=1;i<=n;i++){
ll x,vx,vy;
scanf("%lld%lld%lld",&x,&vx,&vy);
ll res=vy-a*vx;
PLL tmp={vx,vy};
ans+=mp[res]-same[tmp];
mp[res]++;da
same[tmp]++;
}
printf("%lld
",ans*2);//这里乘2是因为ans只记录了会碰撞的点,不是次数
return 0;
}