P9914 「RiOI-03」匀速相遇

题目描述

平面直角坐标系上有 n + m n + m n+m 个点,其中:

  • n n n A \rm A A 类点,它们在初始时依次位于位置 ( 1 , 0 ) , ( 2 , 0 ) , ( 3 , 0 ) , … , ( n , 0 ) (1, 0), (2, 0), (3, 0), \dots, (n, 0) (1,0),(2,0),(3,0),,(n,0)
  • m m m B \rm B B 类点,它们在初始时依次位于位置 ( 0 , 1 ) , ( 0 , 2 ) , ( 0 , 3 ) , … , ( 0 , m ) (0, 1), (0, 2), (0, 3), \dots, (0, m) (0,1),(0,2),(0,3),,(0,m)

在某一个时刻, A , B \rm A, B A,B 类点同时开始运动。具体地:

  • 对于第 i i i A \rm A A 类点,其以 a i a_i ai 个单位长度每秒的速度向上(即 y y y 轴正方向)匀速运动。特别地,若 a i = 0 a_i = 0 ai=0,则该点始终保持静止。
  • 对于第 i i i B \rm B B 类点,其以 b i b_i bi 个单位长度每秒的速度向右(即 x x x 轴正方向)匀速运动。特别地,若 b i = 0 b_i = 0 bi=0,则该点始终保持静止。

你能否帮小 T 解决一个简单的问题:求出有多少点对会在某个时刻相遇,即它们在某一刻共点。

分析

对于两个点如果同为 A \rm A A 类点,或同为 B \rm B B 类点,他们是不会相交的,因为他们的移动方向是不同的,我们假设相交的点编号为 i , j i,j i,j,可以发现他们必然在 ( i , j ) (i,j) (i,j) 相交,而如果 i , j i,j i,j 相交,则他们到 ( i , j ) (i,j) (i,j) 的时间相同,所以:

i b i = j a i \dfrac{i}{b_i}=\frac{j}{a_i} bii=aij

分子分母交叉相乘得:

i × a i = j × b i i \times a_i=j \times b_i i×ai=j×bi

所以我们可以用 map 维护每个 i × a i i \times a_i i×ai 的数量,统计答案时加上 m p [ j × b i ] mp[j \times b_i] mp[j×bi] 的值,注意 a i a_i ai 0 0 0 的情况。

代码

#include 
#define int long long

using namespace std;

const int N = 1e6 + 5;
int n, m, a[N], b[N];
unordered_map <int, int> mp;

signed main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i] != 0){
			mp[i * a[i]] ++;
		} 
	}
	int cnt = 0;
	for(int i = 1; i <= m; i ++){
		cin >> b[i];
		cnt += mp[i * b[i]];
	}
	cout << cnt;
	return 0;
}

你可能感兴趣的:(算法,数据结构,c++)