CF975D Solution

题目链接

题解

设两点碰撞的时间为(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;
}
原文地址:https://www.cnblogs.com/violetholmes/p/14227245.html