1 条题解
-
0
📝 题目大意
从 出发,每秒只能向上下左右移动一格(不能停留),给定 个目标点 和到达时刻 ,判断能否按计划依次到达所有目标点。
💡 解题思路
-
题目分析:这是一个判定性问题,关键在于两点之间的移动约束。数据范围 要求 解决。 严格递增,且 非负,但出发点 在原点,无需特殊处理。
-
算法推导:
- 从 到 所需的最短时间就是曼哈顿距离:。
- 如果可用时间 小于 ,则无法到达,直接输出
No。 - 如果 ,多出的时间 必须被"浪费"掉。由于不能停留,唯一浪费时间的办法是来回走(例如向右走一步再向左走一步),每次来回消耗 2 单位时间。因此 必须是偶数,即 。
- 本质上是坐标奇偶性的约束:曼哈顿距离与时间差的奇偶性必须一致。因为每次移动都会改变坐标和的奇偶性( 的奇偶性每步翻转),而时间每过 1 秒也会翻转一次,所以 与 的奇偶性必须始终相同。
- 代码实现:用
x1, y1, t1记录上一个到达点的坐标和时间(初始为 ),对每个新目标点计算dist和dt,逐一检查两个条件。用标志f标记是否已经输出过No,避免重复输出。
-
边界与细节:
- 题目保证 严格递增,无需排序。
- 注意
f标志的使用:一旦判定为No,后续输入仍需读入(否则会影响下一组数据的读取),但不再进行判断和输出,防止重复输出No。 - 当所有检查通过后(
f == 0),输出Yes。 - 数据范围:,
int足够存储,不会溢出。
⏱️ 复杂度分析
- 时间复杂度:对 个目标点进行一次线性扫描,每次计算曼哈顿距离和奇偶性判断均为 ,总时间复杂度 。
- 空间复杂度:仅需存储 个点的 数组,以及几个辅助变量,总空间复杂度 。
💻 标准代码 (C++)
#include <bits/stdc++.h> #define MAXN 200200 #define MOD 998244353 using namespace std; void solve(){ int n; cin>>n; vector<int>t(n),x(n),y(n); int x1{0},y1{0},t1{0}; // 上一个到达点的坐标和时间,初始为原点时刻0 int f{0}; // 标记是否已经输出过No,防止重复输出 for(int i=0;i<n;i++){ cin>>t[i]>>x[i]>>y[i]; if(f)continue; // 已经判定为不可行,跳过后续判断但仍需读入数据 int dist=abs(x[i]-x1)+abs(y[i]-y1); // 曼哈顿距离:最短所需时间 // 条件1:可用时间不足以覆盖最短距离 if(dist>t[i]-t1){ cout<<"No"<<endl; f=1; } // 条件2:多余时间必须是偶数(来回消耗) if(((t[i]-t1)-dist)%2){ cout<<"No"<<endl; f=1; } x1=x[i]; // 更新上一个到达点 y1=y[i]; t1=t[i]; } if(!f)cout<<"Yes"<<endl; // 所有检查通过 } int main() { solve(); return 0; } -
- 1
信息
- ID
- 846
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者