Codeforces Round #478 (Div. 2) D. Ghosts(数学)
链接
题意:给你一条直线的斜率a和截距b,和某一时刻n个在直线上的点的横坐标,以及沿坐标轴方向的速度。问你这些点在(-∞,+∞)的时间内的碰撞次数。
解析:
设两个点在t时刻相碰,有:
x1+vx1t=x2+vx2t
y1+vy1t=y2+vy2t
消去t,可以得到
x1−x2vx2−vx1=y1−y2vy2−vy1
而在直线上有
y1−y2=a(x1−x2)
进一步整理可以得到
vy2−avx2=vy1−avx1
也就是说 当两个点的 vy−avx 值相等时,两个点就会相碰
开一个map记录每一个 vy−avx 值对应的点的数量
同时也要注意,如果两个点具有相同的vx vy ,两个点相对静止,不会相碰,所以每次统计答案时,除了加上与当前点vy−avx 相同的点的数量,还要减去与当前点相对静止的点的数量(可以另开一个map记录一下)
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define pll pair<ll,ll>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
#define rson rt<<1|1,m+1,r
#define lson rt<<1,l,m
using namespace std;
const int N=1e5+100;
int main()
{
ll n,a,b,ans=0,x,vx,vy;
cin>>n>>a>>b;
map<ll,int>mp;
map<pll,int>mp1;
rep(i,1,n)
{
cin>>x>>vx>>vy;
ll res=vy-a*vx;
pll t=make_pair(vx,vy);
ans+=mp[res]-mp1[t];
mp[res]++;
mp1[t]++;
}
cout<<ans*2<<endl;
return 0;
}