题解
设两点碰撞的时间为(t),则
[egin{cases} x_1+tcdot V_{x1}=x_2+tcdot V_{x2} \y_1+tcdot V_{y1}=y_2+tcdot V_{y2}end{cases}
]
化简合并得
[frac {x_1-x_2}{V_{x2}-V_{x1}}=frac {y_1-y_2}{V_{y2}-V_{y1}}
]
因为(y=ax+b),所以(y_1-y_2=a(x_1-x_2)),原方程可进一步简化为
[V_{y1}-acdot V_{x1}=V_{y2}-acdot V_{x2}
]
因此只需记录与(V_{y}-acdot V_{x})相同的点的个数即可。不过当(V_{x1}=V_{x2})且(V_{y1}=V_{y2})时,满足(V_{y1}-acdot V_{x1}=V_{y2}-acdot V_{x2})但两点不会相遇,因此需要另计录(V_x)与(V_y)都相等的点的个数。具体实现可以使用map,此外,因为碰撞时两个点的经验值都会(+1),答案需要( imes 2)。
AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
map<int,int> qwq;//qwq[i]:vy-a·vx为i的点的个数
map<pair<int,int>,int> same;//same[i]:pair(vx,vy)为i的点的个数
signed main()
{
int n,a,b,ans=0;
scanf("%lld%lld%lld",&n,&a,&b);
int x,vx,vy;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&x,&vx,&vy);
ans+=qwq[vy-a*vx]-same[make_pair(vx,vy)];
qwq[vy-a*vx]++; same[make_pair(vx,vy)]++;
}
printf("%lld",ans*2);
return 0;
}