AcWing 4508. 移动的点

本文探讨了在二维平面上,多个移动点相遇的数学模型。通过分析点的相对速度和位置关系,得出任意两点要么相对静止要么仅相遇一次的结论,并提出了一种利用哈希表进行高效碰撞检测的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
在这里插入图片描述

思路 :

  • 首先我们发现两个点之间最多相遇一次;比如以点a为参考系,那么a相当于静止,如果b会与a相遇,那b只能朝a这一个方向运动,且速度大于0,如果等于0就相对静止永远不可能相遇;因此,我们说,任意两个点要么相对静止,要么只相遇一次,或者错开
  • 在所有点都在y=ax+b上这个时刻看,假设有两个点i和j,以i为参考系,看j的相对速度,j如果能与i相遇,意味着(注意,可能在这个时刻前,也可能在这个时刻后,因此,速度方向有两种,但斜率只需要有一种)j沿着这个直线走,即j相对于i的相对速度的斜率一定等于a,即Vjy−ViyVjx−Vix=a\frac{V_{jy}-V_{iy}}{V_{jx}-V{ix}}=aVjxVixVjyViy=a,即Vjy−aVjx=Viy−aVixV_{jy}-aV{jx}=V_{iy}-aV{ix}VjyaVjx=ViyaVix,同时,两个点不能相对静止
  • wi=vy−avxw_i=v_y-av_xwi=vyavx,若两个点w相同,且相对速度不为0,则这两个点回会相遇
  • 关于判断相对速度大小是否为0,我们将(Vx,Vy)(V_x,V_y)(Vx,Vy)这个数对哈希一下,由于每一个数都是在1e9以内,我们将哈希值设为Base=2e9+1,…,将这个数对变为一个在0~2e9之间的数,因此,可以看成一个2e9+1进制数,这样哈希值就是唯一的了
  • 我们记录速度方向一致的,再记录相对速度大小为0的,用前者的方案数减去后者的方案数
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <deque>
#include <sstream>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#define endl '\n'
#define _(a) cout << #a << ": " << (a) << "    "
#define one first
#define two second
#define pb push_back
using namespace std;
template<class T> void chkmax(T &a, T b) {a = max(a, b);}
template<class T> void chkmin(T &a, T b) {a = min(a, b);}
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
const ll Base = 2e9 + 1, Zero = 1e9;

int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n, a, b;
    cin >> n >> a >> b;
    unordered_map<ll, int> hash1, hash2;
    while (n -- ) {
        int x, vx, vy;
        cin >> x >> vx >> vy;
        hash1[vy - (ll)a * vx] ++ ;
        hash2[(vx + Zero) * Base + vy + Zero] ++ ;
    }
    ll ans = 0;
    for (auto& [k, v] : hash1) ans += v * (v - 1ll);
    for (auto& [k, v] : hash2) ans -= v * (v - 1ll);
    cout << ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值