Codeforces Round #478 (Div. 2) D. Ghosts

傳送門

題意

在一個平面宇宙有很多的靈魂在以固定速度遊蕩,如果兩個靈魂相遇會互相恐嚇對方,相對應的兩個靈魂各自增加一點經驗值。每個靈魂經驗值初始爲零。給定每個靈魂初始的x座標,y座標滿足y=ax+b。然後給出x方向的速度和y方向的速度。數據保證給定靈魂位置不同。這些位置是靈魂飄蕩過程中某一時刻的狀態。要我們求出所有靈魂的經驗值都不增加時總經驗值。

分析

題目給出某一時刻靈魂的位置和靈魂移動的速度。讓我們求所有靈魂最後都不再相遇時靈魂的總經驗值。所有靈魂移動的軌跡是一條直線,我們理所當然的想到了直線相交。但即便軌跡相交也不一定相遇,因爲還有時間的因素。我們可以以時間爲變量,當前座標爲常數建立方程:

xi+VxiTx=xj+VxjTxyi+VyiTy=yj+VyjTyTx=x0ix0jVxjVxiTy=y0iy0jVyjVyiy=ax+bTx=Ty=>x0ix0jVxjVxi=y0iy0jVyjVyi=ax0iax0jVyjVyiresult:aVxjVyj=aVxiVyi

通過上面的一系列推斷我們知道了兩個靈魂是否相遇只和Vx 和Vy、a有關。所以我們只需要求最後一個公式的值如果相等則代表兩靈魂相遇。

注意點

即便公式算出的值相等、也不一定就會相遇。比如速度爲0。 或速度相同但因爲起點不同。軌跡是兩條相互平行的直線。所以我們需要排除這些情況;

/*
    problem: Codeforces Round #478 (Div. 2) D. Ghosts
    author: zxz
    time:
    memory:
    disadvantage:
*/


#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <math.h>
#include <queue>
#include <string>
#include <sstream>
#include <vector>
#include <string.h>
#include <list>
#include <time.h>
using namespace std;

const int maxn = 1e5;
const int INF = 1e9;


void solve()
{
    unsigned long long n, a, b;
    scanf("%llu %llu %llu", &n, &a, &b);
    int  X0, v1, v2;
    map<unsigned long long , int> mp;
    map<pair<int, int>, int> same;
    long long ans = 0;

    while(n--){
        scanf("%d %d %d", &X0, &v1, &v2);
        ans += mp[a*v1 - v2] - same[{v1,v2}];
        mp[a*v1 - v2] ++;
        same[{v1,v2}] ++;
    }

    cout << ans * 2 << endl;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("cin.txt", "r", stdin);
    //freopen("cout.txt", "w", stdout);
    int mao = clock();
#endif
    solve();
#ifndef ONLINE_JUDGE
    cerr << "Time:" << clock() - mao << "ms" << endl;
#endif
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章