行走
[题目链接](https://www.nowcoder.com/practice/9c9835bf3c9c4947bce69e30d4412217)
思路
小美在二维坐标平面上,从 出发,进行
次移动。第
次移动选择满足
的整数
,移动到
。问能否恰好到达
。
三个关键条件
设目标曼哈顿距离 ,总步长和
,最大步长
。
条件一:总步长足够。 显然需要 ,否则无论怎么走都到不了。
条件二:奇偶性匹配。 每步移动 的曼哈顿距离,净位移的曼哈顿距离与
同奇偶(多走的部分必须以"往返"形式抵消,每次抵消消耗 2 的距离)。因此需要
。
条件三:最大步长不能过大。 如果某一步 特别大,剩余所有步的总长
也无法"拉回来"。具体地,
步的可达范围要求净位移至少为
(最大步迈出去,其余步全力往回拉,也只能抵消
的距离)。因此需要
,即
。
可以直觉理解:将最大步固定方向走出去,剩余 步的总长为
,它们可以自由调整方向。如果
,那么剩余步本身就能完全抵消最大步,条件三自动满足。否则至少还有
的"欠债"需要目标距离
来"消化"。
三个条件为何充分
当这三个条件同时满足时,我们总能构造一种合法方案。核心思路是:先用两步"消耗"掉多余的距离 ,再让剩余的步沿着目标方向走。在二维平面中,两步
可以通过在
方向上灵活分配,实现范围
内任意同奇偶曼哈顿距离的净位移。因此只要总量和奇偶都对,就一定有解。
样例演示
样例 1:,起点
,终点
。
。三个条件全满足,输出 YES。
样例 2:,起点
,终点
。
。条件一
满足;条件三
满足;但条件二
为奇数,不满足。输出 NO。
复杂度分析
- 时间复杂度:
,遍历数组求和与最大值。
- 空间复杂度:
,只需常数额外空间。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
long long S = 0, mx = 0;
for(int i = 0; i < n; i++){
long long a;
scanf("%lld", &a);
S += a;
mx = max(mx, a);
}
long long sx, sy, ex, ey;
scanf("%lld%lld%lld%lld", &sx, &sy, &ex, &ey);
long long d = abs(ex - sx) + abs(ey - sy);
long long R = S - mx;
if(d <= S && (S - d) % 2 == 0 && d >= mx - R){
puts("YES");
} else {
puts("NO");
}
}
return 0;
}
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine().trim());
StringBuilder sb = new StringBuilder();
while (T-- > 0) {
int n = Integer.parseInt(br.readLine().trim());
StringTokenizer st = new StringTokenizer(br.readLine().trim());
long S = 0, mx = 0;
for (int i = 0; i < n; i++) {
long a = Long.parseLong(st.nextToken());
S += a;
mx = Math.max(mx, a);
}
st = new StringTokenizer(br.readLine().trim());
long sx = Long.parseLong(st.nextToken());
long sy = Long.parseLong(st.nextToken());
long ex = Long.parseLong(st.nextToken());
long ey = Long.parseLong(st.nextToken());
long d = Math.abs(ex - sx) + Math.abs(ey - sy);
long R = S - mx;
if (d <= S && (S - d) % 2 == 0 && d >= mx - R) {
sb.append("YES\n");
} else {
sb.append("NO\n");
}
}
System.out.print(sb);
}
}

京公网安备 11010502036488号