Can you reach A certain mountain range has N N mo...

创建于:2025年3月26日

使用 O1 回答 Chat01

问题

Can you reach
A certain mountain range has
N
N mountains, all along a line. The peak of the
i
i-th mountain is at a height of
H
i
H
i

.
It is known that adjacent mountain peaks differ in height by exactly
1
1, i.e.

H
i

H
i

1

1
∣H
i

−H
i−1

∣=1 for every
i
i.

On each mountain peak lives a single person.
A person can move from one mountain peak to an adjacent mountain peak (i.e. a person standing on the
i
i-th peak can move to
i

1
i−1 or
i
+
1
i+1).
However, they will refuse to move to a mountain that's of the same height as one that has been visited before.

For example, if the heights are
[
1
,
2
,
3
,
2
,
3
]
[1,2,3,2,3], the person who is initially on the first peak can move to the second and third peaks, but will not move to the fourth (since it has a height of
2
2, which has already been visited along the way).
Similarly, the person initially on the fourth peak can move to the third or the fifth peak, but will not move to the second peak, since it has a height of
2
2 which is the same as the starting height.

Two people are considered to have a friendship between them if they can both reach the same mountain via some sequence of moves.
In the above example of
[
1
,
2
,
3
,
2
,
3
]
[1,2,3,2,3], the people on mountains
2
2 and
3
3 are friends (person
2
2 can move to mountain
3
3), and the people on mountains
1
1 and
4
4 are also friends (they can both move to mountain
3
3). However, the people on mountains
1
1 and
5
5 are not friends, because there's no common mountain where they can meet.

Given the heights of the mountain peaks, find the number of friendships.

Input Format
The first line of input will contain a single integer
T
T, denoting the number of test cases.
Each test case consists of two lines of input.
The first line of each test case contains one integer
N
N — the number of mountain peaks.
The next line contains
N
N space-separated integers
H
1
,
H
2
,

,
H
N
H
1

,H
2

,…,H
N

, describing the mountain heights.
Output Format
For each test case, output on a new line a single integer: the number of friendships.

Constraints
1

T

1
0
5
1≤T≤10
5

1

N

2

1
0
5
1≤N≤2⋅10
5

1

H
i

N
1≤H
i

≤N

H
i

H
i

1

1
∣H
i

−H
i−1

∣=1 for each
1

i
<
N
1≤i<N
The sum of
N
N over all test cases won't exceed
2

1
0
5
2⋅10
5
.
Sample 1:
Input
Output
2
5
3 4 5 4 3
4
1 2 1 2
10
5
Explanation:
Test case
1
1: Every person is able to reach the highest mountain, i.e.
5
5. Since for every pair of people there's a mountain they can both reach, every pair of people will be friends.

Test case
2
2: The friendships are as follows:

Persons
1
1 and
2
2 are friends: they're already adjacent to each other so one of them can just move to the other.
Similarly
(
2
,
3
)
(2,3) and
(
3
,
4
)
(3,4) are friends.
Persons
1
1 and
3
3 are friends: they can both move to mountain
2
2 and meet there.
Similarly, persons
2
2 and
4
4 are friends, since they can meet at mountain
3
3.
However, there's no way for persons
1
1 and
4
4 to ever meet.
The total number of friendships is hence
5
5.

Did you like the problem statement?
More Info
Time limit1 secs
Memory limit1.5 GB
Source Limit50000 Bytes
import java.util.;
import java.lang.
;
import java.io.*;

class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here

}

}

write a java solution

回答

java
import java.util.*; import java.lang.*; import java.io.*; class Codechef { // We will implement the logic as follows: // // 1) If there is only 1 peak (N=1), no pairs can form, answer = 0. // 2) Otherwise, build an array S of length N-1 where // S[i] = +1 if H[i+1] > H[i], or -1 if H[i+1] < H[i]. // (Note that the problem guarantees |H[i+1] - H[i]| = 1, so no 0-differences.) // // 3) We then break this S array into "runs" of consecutive +1s or -1s. Each run // in S corresponds to a strictly-monotonic subarray in H. Concretely, we scan // S from left to right and cut a new run whenever the sign changes from +1 to -1 // or from -1 to +1. // // Example: H = [3, 4, 5, 4, 3] // S = [+1, +1, -1, -1] // This breaks into two runs in terms of indices in S: // run1: [0..1] => covers H indices [0..2] (3 -> 4 -> 5) // run2: [2..3] => covers H indices [2..4] (5 -> 4 -> 3) // // 4) For each run r that covers a segment [startH..endH] of H (inclusive), // let size = (endH - startH + 1). All peaks in that run can pairwise meet // (since within a strictly monotonic segment, you never repeat a height). // Therefore the number of "internal" friendships contributed by that run is // size * (size - 1) / 2 // // 5) Adjacent runs in S share exactly one boundary index in H. Let that boundary // index be b. If run r1 covers [a..b], run r2 covers [b..c], and r1 is strictly // increasing while r2 is strictly decreasing (or vice versa), then any peak i // in r1 and peak j in r2 can meet at b (because i->...->b is strictly monotonic, // and j->...->b is strictly monotonic, with one sign-change at b). // We must, however, be careful to exclude pairs that are already counted // in the runs themselves (notably those involving b in both runs). // // It turns out the correct count of new "cross-run" pairs introduced by // that shared boundary b is: // (size(r1) - 1) * (size(r2) - 1). // // Explanation sketch: // - run r1 has size(r1) indices, all of which include b. // - run r2 has size(r2) indices, also including b. // - The "full cross product" size(r1)*size(r2) counts (b,b) (not a pair), // and pairs (b,x) or (x,b) which are already in an internal run's count. // - After carefully excluding those duplicates, the net new count is // (size(r1)-1) * (size(r2)-1). // // 6) Summing (a) all intra-run pairs plus (b) the cross-run pairs for each boundary // gives the total number of friendships. // // Complexity: O(N) per test. Since the problem constraints say the sum of N over // all testcases is at most 2*10^5, this will run efficiently. public static void main(String[] args) throws java.lang.Exception { FastIO in = new FastIO(); int T = in.nextInt(); StringBuilder sb = new StringBuilder(); // We will process each test in O(N), building the "runs" of +1 or -1 in S. // Then we add up the internal pairs plus cross-run pairs. while (T-- > 0) { int N = in.nextInt(); int[] H = new int[N]; for (int i = 0; i < N; i++) { H[i] = in.nextInt(); } // If there is only one peak, no pairs can form if (N == 1) { sb.append(0).append('\n'); continue; } // Build the sign array S of length N-1 int[] S = new int[N-1]; for (int i = 0; i < N - 1; i++) { if (H[i+1] > H[i]) { S[i] = 1; } else { S[i] = -1; } } // Identify consecutive runs in S ArrayList<int[]> runs = new ArrayList<>(); // Each element in 'runs' will be an int[2] = {startInS, endInS} // meaning the run covers S indices [startInS..endInS], inclusive. int start = 0; int sign = S[0]; for (int i = 1; i < N - 1; i++) { if (S[i] != sign) { // We close the previous run [start.. i-1] runs.add(new int[]{start, i - 1}); // Start a new run at i start = i; sign = S[i]; } } // Add the final run from 'start' to N-2 runs.add(new int[]{start, N - 2}); // Now 'runs' covers the entire array S in consecutive monotonic segments. // Each run [a..b] in S coverage corresponds to H coverage [a..(b+1)]. // The size of that run in H is (b - a + 2). long totalFriendships = 0; long[] runSizes = new long[runs.size()]; // 1) Sum of internal pairs for (int i = 0; i < runs.size(); i++) { int[] r = runs.get(i); int a = r[0], b = r[1]; long size = (b - a + 2); // number of H-indices in this run runSizes[i] = size; // number of internal pairs is size * (size - 1) / 2 totalFriendships += size * (size - 1) / 2; } // 2) Sum of cross-run pairs between adjacent runs // If runs i and i+1 share a boundary in H at index = (runs[i].end + 1) // Then cross-run = (runSizes[i] - 1) * (runSizes[i+1] - 1). for (int i = 0; i + 1 < runs.size(); i++) { // We'll verify the boundary is consecutive in H. In terms of S coverage: // run i => covers [a..b] in S => H coverage [a.. b+1] // run i+1 => covers [c..d] in S => H coverage [c.. d+1] // They share boundary if (b+1 == c). We'll check that just to be safe. int[] r1 = runs.get(i); int[] r2 = runs.get(i + 1); // H-end for run r1 is (r1[1] + 1) // H-start for run r2 is r2[0] if (r1[1] + 1 == r2[0]) { long cross = (runSizes[i] - 1) * (runSizes[i + 1] - 1); totalFriendships += cross; } // Else, no shared boundary => no cross-run pairs. } sb.append(totalFriendships).append('\n'); } System.out.print(sb); } // A simple fast IO helper (Scanner can be slow for large input). static class FastIO { private BufferedReader br; private StringTokenizer st; public FastIO() { br = new BufferedReader(new InputStreamReader(System.in)); } String next() throws IOException { while (st == null || !st.hasMoreTokens()) { st = new StringTokenizer(br.readLine()); } return st.nextToken(); } int nextInt() throws IOException { return Integer.parseInt(next()); } long nextLong() throws IOException { return Long.parseLong(next()); } } }

Explanation of the core ideas:

• Because adjacent heights differ by exactly 1, any path that changes “direction” (from going up to going down or vice versa) would necessarily revisit a height. Hence a person’s movements must lie entirely in a strictly-increasing or strictly-decreasing subarray of the heights.

• We find these maximal strictly-monotonic “runs” by scanning the sign array S (where S[i] = ±1 depending on whether H[i+1] > H[i] or H[i+1] < H[i]).

• Within each run, all persons on those peaks can meet each other (they form an internal complete sub-group).

• Additionally, at each boundary between an “up” run and a “down” run (or vice versa), everyone from one run can meet everyone from the neighboring run at the boundary index (so that adds (size(run1) - 1) × (size(run2) - 1) new friendships).

• Summing these internal and cross-run contributions yields the answer.

分享这个问答