zoukankan      html  css  js  c++  java
  • 【map离散&容斥】Ghosts @Codeforces Round #478 (Div. 2) D

    传送门
    题意:给你一条直线的斜率a和截距b,和某一时刻n个在直线上的点的横坐标,以及沿坐标轴方向的速度。问你这些点在(-∞,+∞)的时间内的碰撞次数。

    solution
    设两个点在t时刻相碰,有:

    x1+vx1t=x2+vx2tx1+vx1t=x2+vx2t
    y1+vy1t=y2+vy2ty1+vy1t=y2+vy2t


    消去t,可以得到

    x1x2vx2vx1=y1y2vy2vy1x1−x2vx2−vx1=y1−y2vy2−vy1


    而在直线上有

    y1y2=a(x1x2)y1−y2=a(x1−x2)


    进一步整理可以得到

    vy2avx2=vy1avx1vy2−avx2=vy1−avx1


    也就是说 当两个点的 vyavxvy−avx 值相等时,两个点就会相碰
    开一个map记录每一个 vyavxvy−avx 值对应的点的数量
    同时也要注意,如果两个点具有相同的vxvx vyvy ,它们的vyavxvy−avx 也是相同的,但此时两个点相对静止 不会相碰
    所以每次统计答案时,除了加上与当前点vyavxvy−avx 相同的点的数量,还要减去与当前点相对静止的点的数量(可以另开一个map记录一下)

    #define IN_LB() freopen("C:\Users\acm2018\Desktop\in.txt","r",stdin)
    #define OUT_LB() freopen("C:\Users\acm2018\Desktop\out.txt","w",stdout)
    #define IN_PC() freopen("C:\Users\hz\Desktop\in.txt","r",stdin)
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef pair<ll,ll> pll;
    map<ll,int> mp;
    map<pll,int> same;
    
    int main() {
    //    IN_LB();
        ll n,a,b,ans=0;
        scanf("%lld%lld%lld",&n,&a,&b);
        for(int i=0; i<n; i++) {
            ll x,vx,vy;
            scanf("%lld%lld%lld",&x,&vx,&vy);
            ll res = vy-a*vx;
            pll node = {vx,vy};
            ans+=mp[res] - same[node];
            mp[res]++;
            same[node]++;
        }
        printf("%lld
    ",ans*2);
        return 0;
    }
    
  • 相关阅读:
    Alpha阶段项目复审
    复审与事后分析
    测试与发布(Alpha版本)
    第七天
    第六天
    团队作业第4周——项目冲刺
    第一天
    第二天
    第四天
    第五天
  • 原文地址:https://www.cnblogs.com/NeilThang/p/9356611.html
Copyright © 2011-2022 走看看