反向考虑,以所有可以直接到达的点作为起点。
若是 i → j,i j 处的值奇偶不同,那么 i 的结果就为1,i 是起点。
若是 i → j,i j 处的值奇偶相同,那么就以 j → i 为边建图。
public static void solve(Kattio kattio) {
int n = kattio.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = kattio.nextInt();
}
int[] res = new int[n];
List<Integer>[] graph = new ArrayList[n];
for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
int prev = i - a[i];
int next = i + a[i];
int odd = a[i] % 2;
if ((prev >= 0 && a[prev] % 2 != odd) || (next < n && a[next] % 2 != odd)) {
res[i] = 1;
queue.offer(i);
} else {
res[i] = -1;
}
if (prev >= 0 && a[prev] % 2 == odd) {
graph[prev].add(i);
}
if (next < n && a[next] % 2 == odd) {
graph[next].add(i);
}
}
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int id = queue.poll();
for (Integer next : graph[id]) {
if (res[next] < 0) {
res[next] = res[id] + 1;
queue.offer(next);
}
}
}
}
StringBuilder sb = new StringBuilder();
for (int re : res) {
sb.append(re).append(" ");
}
kattio.println(sb);
}