你有一个机器人,这个机器人在一维坐标轴上移动。你可以给这个机器人下达指令,指令的形式为
t
i
,
x
i
t_i, x_i
ti,xi ,意味着机器人在第
t
i
t_i
ti秒的时候获得一条指令,此时这个机器人以
1
/
s
1/s
1/s的速度从现在的位置开始向
x
i
x_i
xi移动。若机器人执行当前指令的过程中收到其他命令,那么其他命令会被忽略。
假设当前命令为
t
i
,
x
i
t_i, x_i
ti,xi , 若机器人在
t
i
t_i
ti 到
t
i
+
1
t_{i+1}
ti+1这个时间区间(包括边界)内到达过
x
i
x_i
xi 这个位置,则称这条命令被成功执行。
对于最后一条命令
t
n
,
x
n
t_n, x_n
tn,xn ,我们认为有一个
t
n
+
1
=
∞
t_{n+1}=∞
tn+1=∞ 。
思路:
从第一条命令开始,我们记录它的起始时间
s
t
a
r
t
_
t
i
m
e
start\_time
start_time ,结束时间
e
n
d
_
t
i
m
e
end\_time
end_time ,之后排着扫命令:
若命令的
t
i
t_i
ti 小于
s
t
a
r
t
_
e
n
d
start\_end
start_end , 那么就算出
t
i
t_i
ti 时机器人的位置和
m
i
n
(
t
i
+
1
,
e
n
d
_
t
i
m
e
)
min(t_{i+1}, end\_time)
min(ti+1,end_time) 时机器人的位置,若
x
i
x_i
xi 在这个区间内,那么这条命令就算被成功执行了;
若命令的
t
i
t_i
ti 大于等于
s
t
a
r
t
_
t
i
m
e
start\_time
start_time , 那么就更新
s
t
a
r
t
_
t
i
m
e
start\_time
start_time 和
e
n
d
t
i
m
e
end_time
endtime 。
本题有一些处理上的小技巧,可以在代码中看到。
此外这道题个地方需要注意:题目里说的认为有一个
t
n
+
1
=
∞
t_{n+1}=∞
tn+1=∞ , 这里我最开始的代码无穷取了
0
x
3
F
3
F
3
F
3
F
0x3F3F3F3F
0x3F3F3F3F , 但是这里无穷取这个值会出问题,因为他的范围是从
−
1
0
9
<
=
x
i
<
=
1
0
9
-10^9 <= x_i <= 10^9
−109<=xi<=109, 若数据给了从最左边到最右边是最后一个指令,那么取这个值会导致它不能走到最右边。(这个地方卡了我一下午。。)
AC代码:
#include <cstdio>
#include <algorithm>
typedef long long ll;
const int maxn = 1e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;
struct node {
ll t, p;
}a[maxn];
int main () {
int T, n;
scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
for (int i = 0; i < n; i++) {
scanf ("%lld %lld", &a[i].t, &a[i].p);
}
a[n].t = inf;
ll start_pos = 0;
ll end_pos = 0;
ll start_time = 0;
ll end_time = -1;
ll dir = 0;
int ans = 0;
for (int i = 0; i < n; i++) {
if (a[i].t >= end_time) {
start_pos = end_pos;
end_pos = a[i].p;
start_time = a[i].t;
end_time = start_time + std::abs(a[i].p - start_pos);
dir = (a[i].p - start_pos) == 0 ? 0 : (a[i].p - start_pos) / std::abs(a[i].p - start_pos);
}
ll s = start_pos + (a[i].t - start_time) * dir;
ll t = start_pos + (a[i + 1].t - start_time) * dir;
if (a[i + 1].t > end_time) {
t = end_pos;
}
if (s > t) std::swap (s, t);
if (a[i].p >= s && a[i].p <= t) {
ans++;
}
}
printf ("%d\n", ans);
}
return 0;
}