PDF
1Doomsday FuelContents ............................................................................................... 1 ............................................................................................. 3 ............................................................................................... 5Doomsday Fuel 2[ [0,1,0,0,0,1], # s0, the initial state, goes to s1 and s5 with equal probability [4,0,0,3,2,0], # s1 can become s0, s3, or s4, but with different probabilities [0,0,0,0,0,0], # s2 is terminal, and unreachable (never observed in practice) [0,0,0,0,0,0], # s3 is terminal [0,0,0,0,0,0], # s4 is terminal [0,0,0,0,0,0], # s5 is terminal] 3 4[0,1,0,0,0,1], # s0, the initial state, goes to s1 and s5 with equal probability[4,0,0,3,2,0], # s1 can become s0, s3, or s4, but with different probabilities[0,0,0,0,0,0], # s2 is terminal, and unreachable (never observed in practice)[0,0,0,0,0,0], # s3 is terminal[0,0,0,0,0,0], # s4 is terminal[0,0,0,0,0,0], # s5 is terminal 5Input:Solution.solution({ {0, 2, 1, 0, 0}, {0, 0, 0, 3, 4}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}})Output: [7, 6, 8, 21]便使public class Fraction { private final int numerator; private final int denominator; 6 public Fraction(int numerator, int denominator) { if (denominator == 0) { throw new IllegalArgumentException("Denominator should not be zero"); } this.numerator = numerator; this.denominator = denominator; }}使public static int gcd(int m, int n) { return m % n == 0 ? n : gcd(n, m % n);}public static int lcm(int m, int n) { return m * n / gcd(m, n);}public Fraction reduce() { int gcd = Math.gcd(numerator, denominator); int n = numerator / gcd, d = denominator / gcd; boolean swap = d < 0; return new Fraction(swap ? -n : n, swap ? -d : d);}public Fraction negative() { return new Fraction(-numerator, denominator);}public Fraction reciprocal() { return new Fraction(denominator, numerator);}public Fraction convert(int common) { int factor = common / denominator; return new Fraction(numerator * factor, common);}public Fraction add(Fraction another) { int common = Math.lcm(denominator, another.denominator); Fraction a = convert(common), b = another.convert(common); 7 return new Fraction(a.numerator + b.numerator, common) .reduce();}public Fraction subtract(Fraction another) { return add(another.negative());}public Fraction multiply(Fraction another) { return new Fraction(numerator * another.numerator, denominator * another.denominator) .reduce();}public Fraction divide(Fraction another) { return multiply(another.reciprocal());}使public class Matrix { private final Fraction[][] matrix; private final int rows; private final int columns; public Matrix(int rows, int columns) { this.rows = rows; this.columns = columns; this.matrix = new Fraction[rows][columns]; }}public Matrix subtract(Matrix another) { if (this.rows != another.rows || this.columns != another.columns) { throw new IllegalArgumentException("Unable to add two matrix with different size"); } Fraction[][] result = new Fraction[rows][columns]; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { result[i][j] = matrix[i][j].subtract(another.matrix[i][j]); } } return new Matrix(result, rows, columns);} 8public Matrix multiply(Matrix another) { if (this.columns != another.rows) { throw new IllegalArgumentException("Unable to add two matrix with different size"); } Matrix r = new Matrix(rows, another.columns); for (int i = 0; i < rows; i++) { for (int j = 0; j < another.columns; j++) { Fraction sum = new Fraction(0, 1); for (int m = 0; m < columns; m++) { sum = sum.add(matrix[i][m].multiply(another.matrix[m][j])); } r.matrix[i][j] = sum; } } return r;}public Matrix complementMinor(int row, int column) { Matrix m = new Matrix(rows - 1, columns - 1); int rowOffset = 0; for (int i = 0; i < rows; i++) { if (i == row) { continue; } int columnOffset = 0; for (int j = 0; j < columns; j++) { if (j == column) { continue; } m.getMatrix()[rowOffset][columnOffset] = matrix[i][j]; columnOffset++; } rowOffset++; } return m;} 9public Fraction determinantValue() { if (rows != columns || rows < 1) { throw new IllegalArgumentException("Not supported"); } if (rows == 1) { return matrix[0][0].reduce(); } else if (rows == 2) { return matrix[0][0].multiply(matrix[1][1]).subtract(matrix[0][1].multiply(matrix[1][0])); } else { Fraction sum = new Fraction(0, 1); for (int i = 0; i < columns; i++) { Fraction sign = Fraction.of(Math.pow(-1, i)); sum = sum.add(matrix[0][i].multiply(sign.multiply(complementMinor(0, i).determinantValue()))); } return sum; }}public Matrix adjugateMatrix() { Matrix m = new Matrix(rows, columns); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { Fraction sign = Fraction.of(Math.pow(-1, (i + j))); m.matrix[j][i] = sign.multiply(complementMinor(i, j).determinantValue()); } } return m;}public Matrix inverse() { Fraction f = determinantValue(); Matrix adjugateMatrix = adjugateMatrix(); Matrix m = new Matrix(rows, columns); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { m.matrix[i][j] = adjugateMatrix.matrix[i][j].divide(f); } } return m;} 10public static int[] solution(int[][] nums) { int totalStates = nums.length, absorbingStates = 0; Set<Integer> absorbingStateIds = new HashSet<>(); for (int i = 0; i < totalStates; i++) { if (sum(nums[i]) == 0) { absorbingStateIds.add(i); } } absorbingStates = absorbingStateIds.size(); int[][] transformed = new int[totalStates][totalStates]; int [] indexMapping = new int[totalStates]; int offset = 0; for (int i = 0; i < totalStates; i++) { if(!absorbingStateIds.contains(i)) indexMapping[offset++] = i; } for(int id: absorbingStateIds){ indexMapping[offset++] = id; } for(int i = 0; i < totalStates; i++) { for(int j = 0; j < totalStates; j++) { transformed[i][j] = nums[indexMapping[i]][indexMapping[j]]; } } nums = transformed; // ...}Matrix matrixQ = new Matrix(transientStates, transientStates), matrixR = new Matrix(transientStates, absorbingStates), matrixI = new Matrix(transientStates, transientStates);for (int i = 0; i < transientStates; i++) { int common = sum(nums[i]); for (int j = 0; j < transientStates; j++) { matrixQ.getMatrix()[i][j] = new Fraction(nums[i][j], common); matrixI.getMatrix()[i][j] = i == j ? new Fraction(1, 1) : new Fraction(0, 1); }}for (int i = 0; i < transientStates; i++) { int common = sum(nums[i]); 11 for (int j = 0; j < absorbingStates; j++) { matrixR.getMatrix()[i][j] = new Fraction(nums[i][j + transientStates], common); }}Matrix matrixN = matrixI.subtract(matrixQ).inverse();Matrix matrixB = matrixN.multiply(matrixR);int[] result = new int[matrixB.getColumns() + 1];int lcm = 0;for (int i = 0; i < matrixB.getColumns(); i++) { if (matrixB.getMatrix()[0][i].getNumerator() == 0) { continue; } if (lcm == 0) { lcm = matrixB.getMatrix()[0][i].getDenominator(); } else { lcm = Math.lcm(lcm, matrixB.getMatrix()[0][i].getDenominator()); }}for (int i = 0; i < matrixB.getColumns(); i++) { result[i] = matrixB.getMatrix()[0][i].getNumerator() * lcm / matrixB.getMatrix()[0][i].getDenominator();}result[result.length - 1] = lcm;Test Case 3foobar:~/doomsday-fuel solee.linux$ verify Solution.java Verifying solution...Test 1 passed!Test 2 passed!Test 3 failed [Hidden]Test 4 passed! [Hidden]Test 5 passed! [Hidden]Test 6 passed! [Hidden]Test 7 passed! [Hidden]Test 8 passed! [Hidden]Test 9 passed! [Hidden]Test 10 passed! [Hidden]

HTML view coming soon.

Download PDF for the full formatted version.