撞车
Description
在一条环形公路上有N辆车,每辆车有一个初始位置,并且朝顺时针或逆时针方向分别以固定的速度行驶。现在你需要判断在T时间范围内最多有多少对车可能发生相撞。当然,如同电影中那样,我们不能忽略追尾的情况(其实撞车往往都是追尾)。
像台词中所说的那样,“我们总是躲在冰冷的建筑后面,我想我们很怀念那种触摸的感觉,我们彼此相撞,只是为了感觉到彼此的存在”。所以对于每两辆车来说撞一次也就够了。如果他们撞了好几次,统计一次也就够了。当然,如果两辆一开始就在同一个位置,那么也要将他们统计进去。撞完继续开。
Input Format
输入第一行包含三个整数L,T和N,其中L表示环形公路的周长。以下N行每行两个整数分别表示相应的车的初始位置以及行驶速度Vi。速度为正表示顺时针,速度为负表示逆时针。
Output Format
输出仅包含一个整数,即答案。
Sample Input
4 1 4 0 1 0 2 1 1 3 -1
Sample Output
4
Hint
对于20%的数据,有1 ≤ N ≤ 1000;
对于100%的数据,有1 ≤ L ≤ 10000,1 ≤ T ≤ 10000,1 ≤ N ≤ 50000,|Vi|<=20。
分析:
在环状路上车相撞,如果移到直线上,就是距离为0或距离为L,先按起点位置排列,然后比较终点位置,树状数组搞一搞就好了。(需要注意的是V可以是负数,所以要加上一个固定值)。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 struct car 6 { 7 int from, to; 8 } c[50050]; 9 10 int l, t, n, p, v, ans; 11 int tree[1000000]; 12 13 bool cmp (car c1, car c2) 14 { 15 if (c1.from == c2.from) 16 return c1.to > c2.to; 17 return c1.from < c2.from; 18 } 19 20 inline int lowbit (int x) 21 { 22 return x & (-x); 23 } 24 25 void modify (int x, int add) 26 { 27 for (int i = x; i <= 500000; i += lowbit (i)) 28 tree[i] += add; 29 } 30 31 int sum (int x) 32 { 33 int ret = 0; 34 for (int i = x; i; i -= lowbit(i)) 35 ret += tree[i]; 36 return ret; 37 } 38 39 int main () 40 { 41 scanf ("%d %d %d", &l, &t, &n); 42 for (int i = 0; i < n; i++) 43 { 44 scanf ("%d %d", &p, &v); 45 c[i].from = p; 46 c[i].to = p + v * t; 47 } 48 std::sort (c, c + n, cmp); 49 ans = 0; 50 for (int i = 0; i < n; i++) 51 { 52 modify (c[i].to + 250000, 1); 53 ans += i - sum (c[i].to + 250000 - 1) + sum (c[i].to + 250000 - l); 54 } 55 printf ("%d\n", ans); 56 }
Your eyes light up the world when you smile.