Solution 1:
First set aN=0. Next, we determine ai for i=N−1,N−2,…,1 in that order. We know that ai=ai+1±ri,i+1. We can first try setting ai=ai+1+ri,i+1; if this is incompatible with some ri,j then set ai=ai+1−ri,i+1 instead. Using induction, it may be proven that this recovers the original array up to a negation and a translation.
Ben's code:
N = int(input()) difs = [list(map(int, input().split())) for _ in range(N)] ans = [0]*N for i in reversed(range(N-1)): def ok(): mx = -float('inf') mn = float('inf') for j in range(i,N): mx = max(mx, ans[j]) mn = min(mn, ans[j]) if mx-mn != difs[i][j-i]: return False return True ans[i] = ans[i+1] + difs[i][1] if not ok(): ans[i] = ans[i+1] - difs[i][1] assert ok() print(" ".join(map(str, ans)))
Solution 2:
Consider the case where every two consecutive elements of a are distinct (that is, ri,i+1≠0 for all 1≤i<N). Then given ai, ai+1, ri+1,i+2 and ri,i+2, we can uniquely determine ai,i+2. This gives us a solution that runs in linear time after reading in the input: set a1=0, a2=r1,2, and then use the observation above to uniquely determine a3,…,aN. Handling the case where consecutive elements of a can be equal requires a bit more care.
Danny Mittal's code:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.StringJoiner; import java.util.StringTokenizer; public class ArrayDifferences { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine()); int[][] differences = new int[n][n]; for (int j = 0; j < n; j++) { StringTokenizer tokenizer = new StringTokenizer(in.readLine()); for (int k = j; k < n; k++) { differences[j][k] = Integer.parseInt(tokenizer.nextToken()); } } List<Integer> distinct = new ArrayList<>(); distinct.add(0); for (int j = 1; j < n; j++) { if (differences[j - 1][j] != 0) { distinct.add(j); } } int[] answer = new int[n]; if (distinct.size() > 1) { answer[distinct.get(1)] = differences[0][distinct.get(1)]; for (int j = 2; j < distinct.size(); j++) { int a = distinct.get(j - 2); int b = distinct.get(j - 1); int c = distinct.get(j); int sign = differences[a][c] == differences[a][b] + differences[b][c] ? 1 : -1; answer[c] = answer[b] + (sign * Integer.signum(answer[b] - answer[a]) * differences[b][c]); } for (int j = 1; j < n; j++) { if (differences[j - 1][j] == 0) { answer[j] = answer[j - 1]; } } } StringJoiner joiner = new StringJoiner(" "); for (int j = 0; j < n; j++) { joiner.add("" + answer[j]); } System.out.println(joiner); } }