撞车

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
", ans);
56 }
原文地址:https://www.cnblogs.com/lightning34/p/4377667.html