import java.io.*; import java.util.*; import java.awt.*; import java.awt.geom.*; /**** * Traveling salesman, validating path and calculating length * * Usage: java Judge pointset.in [1] < PATH */ public class Judge { public static void main(String[] s) { tk = new StreamTokenizer[2]; tk[0] = new StreamTokenizer(System.in); try { tk[1] = new StreamTokenizer(new FileInputStream(s[0])); } catch(Exception e) { e.printStackTrace(); } for (int i = 0; i < tk.length; ++i) { tk[i].resetSyntax(); tk[i].whitespaceChars(0,32); tk[i].wordChars(33,255); eat(i); } int n = INT(1); ut.println("Number of points is " + n); ut.println("Now validating path..."); int[] u = new int[n]; int[] p = new int[n]; String t = null; for (int i = 0; i < n; ++i) { try { t = STR(0); if (t == null) { ut.println("Too few indices (" + i + ") in path!"); ut.println("Now quitting.."); return; } p[i] = Integer.parseInt(t); if (p[i] < 0 || p[i] >= n) { ut.println("Index #" + (i+1) + " (" + t + ") is out of range!"); ut.println("Now quitting.."); return; } else if (u[p[i]] > 0) { ut.println("Index " + t + " is visited twice (#" + (i+1) + " and #" + u[p[i]] + ")!"); ut.println("Now quitting.."); return; } u[p[i]] = i; } catch (NumberFormatException e) { ut.println("Index #" + (i+1) + " (" + t + ") is not an integer!"); ut.println("Now quitting.."); return; } } ut.println("Path is valid, now calculating length..."); double[][] po = new double[2][n]; for (int i = 0; i < n; ++i) { po[0][i] = DBL(1); po[1][i] = DBL(1); } double l = 0; for (int i = 0; i < n - 1; ++i) { l += Math.sqrt((po[0][p[i]] - po[0][p[i+1]])*(po[0][p[i]] - po[0][p[i+1]]) + (po[1][p[i]] - po[1][p[i+1]])*(po[1][p[i]] - po[1][p[i+1]])); } l += Math.sqrt((po[0][p[0]] - po[0][p[n-1]])*(po[0][p[0]] - po[0][p[n-1]]) + (po[1][p[0]] - po[1][p[n-1]])*(po[1][p[0]] - po[1][p[n-1]])); System.out.println("Length is " + l); if (s.length > 1) { Brett b = new Brett(); double fact = 1; for (int i = 0; i < n-1; ++i) { b.add(new Line2D.Double(fact*po[0][p[i]], fact*po[1][p[i]], fact*po[0][p[i+1]], fact*po[1][p[i+1]])); b.add(new Rectangle((int) (fact*po[0][i]) - 1, (int) (fact*po[1][i]) - 1, 3, 3)); } b.add(new Line2D.Double(fact*po[0][p[0]], fact*po[1][p[0]], fact*po[0][p[n-1]], fact*po[1][p[n-1]])); b.add(new Rectangle((int) (fact*po[0][n-1]) - 1, (int) (fact*po[1][n-1]) - 1, 3, 3)); b.go(); } return; } static int INT(int t) { return Integer.parseInt(STR(t)); } static double DBL(int t) { return Double.parseDouble(STR(t)); } static void eat(int t) { try { tk[t].nextToken(); } catch(Exception e) { e.printStackTrace(); } } static String STR(int t) { String s = tk[t].sval; eat(t); return s; } static StreamTokenizer[] tk; static PrintStream ut = System.out; static int P,Q; }