CF975D Solution

题目链接

题解

设两点碰撞的时间为\(t\),则

\[\begin{cases} x_1+t\cdot V_{x1}=x_2+t\cdot V_{x2} \\y_1+t\cdot V_{y1}=y_2+t\cdot 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}-a\cdot V_{x1}=V_{y2}-a\cdot V_{x2} \]

因此只需记录与\(V_{y}-a\cdot V_{x}\)相同的点的个数即可。不过当\(V_{x1}=V_{x2}\)\(V_{y1}=V_{y2}\)时,满足\(V_{y1}-a\cdot V_{x1}=V_{y2}-a\cdot V_{x2}\)但两点不会相遇,因此需要另计录\(V_x\)\(V_y\)都相等的点的个数。具体实现可以使用map,此外,因为碰撞时两个点的经验值都会\(+1\),答案需要\(\times 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;
}
posted @ 2021-01-03 22:27  violet_holmes  阅读(54)  评论(0编辑  收藏  举报