/** * Solution to problem "Sisco's Universe" * * This solution uses just one class to keep it simple. * Arcs are modeled by references between Sectors. * The algorithm is a one-way breadth-first search. * (All arc costs are the same.) * Paths are represented by backward links between Sectors. * */ /* package org.amaze.crypt; */ import java.util.*; import java.io.*; public class Sisco { Sisco[] links = new Sisco[0]; Sisco path; int id; void addLink(Sisco sector) { Sisco[] newLinks = new Sisco[links.length + 1]; for (int i = 0; i < links.length; i++) { newLinks[i] = links[i]; } newLinks[links.length] = sector; links = newLinks; } static Sisco[] init(int w, int h, int[][] holes) { Sisco[] sectors = new Sisco[w * h]; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { sectors[x + y * w] = new Sisco(); sectors[x + y * w].id = x + y * w + 1; } } for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { Sisco s = sectors[x + y * w]; if (x > 0) { s.addLink(sectors[(x - 1) + y * w]); } if (x < w - 1) { s.addLink(sectors[(x + 1) + y * w]); } if (y > 0) { s.addLink(sectors[x + (y - 1) * w]); } if (y < h - 1) { s.addLink(sectors[x + (y + 1) * w]); } } } for (int i = 0; i < holes.length; i++) { int start = holes[i][0]; int finish = holes[i][1]; sectors[start - 1].addLink(sectors[finish - 1]); sectors[finish - 1].addLink(sectors[start - 1]); } return sectors; } static Sisco findPath(Sisco start, Sisco finish) { Vector nodes = new Vector(); Vector newNodes = new Vector(); start.path = new Sisco(); nodes.addElement(start); if (start.id == finish.id) return finish; for (int d = 0; true; d++) { for (int n = 0; n < nodes.size(); n++) { Sisco node = (Sisco) nodes.elementAt(n); for (int k = 0; k < node.links.length; k++) { Sisco link = node.links[k]; if (link.path == null) { link.path = node; if (link == finish) { return link; } newNodes.addElement(link); } } } Vector oldNodes = nodes; nodes = newNodes; newNodes = oldNodes; newNodes.removeAllElements(); } } static void dump(Sisco path, int[][] holes, String[] names, PrintWriter out) { Vector sectors = new Vector(); for (Sisco s = path; s.path != null; s = s.path) { sectors.addElement(s); } out.print( "Trip from " + ((Sisco) sectors.elementAt(sectors.size() - 1)).id + " to " + ((Sisco) sectors.elementAt(0)).id + " takes " + (sectors.size() - 1) + " days"); out.println(); // out.close(); } static void parse(String filename, String output) { try { int trip1 = 0, trip2 = 0; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String line; PrintWriter out = new PrintWriter(System.out); while ((line = in.readLine()) != null) { StringTokenizer t = new StringTokenizer(line, "x"); // t.nextToken().trim(); int h = Integer.parseInt(t.nextToken().trim()); int w = Integer.parseInt(t.nextToken().trim()); Vector ho = new Vector(); Vector n = new Vector(); while ((line = in.readLine()) != null) { t = new StringTokenizer(line, ","); String name = t.nextToken().trim(); int start = Integer.parseInt(t.nextToken().trim()); int finish = Integer.parseInt(t.nextToken().trim()); if (name.equals("Trip")) { trip1 = start; trip2 = finish; break; } else { ho.addElement(new int[] {start, finish}); n.addElement(name); } } int[][] holes = new int[ho.size()][]; String[] names = new String[n.size()]; ho.copyInto(holes); n.copyInto(names); solve(w, h, trip1, trip2, holes, names, out); line = in.readLine(); //blankline } in.close(); out.close(); } catch(Exception e) { e.printStackTrace(); } } static void solve(int w, int h, int trip1, int trip2, int[][] holes, String[] names, PrintWriter out) { Sisco[] sectors = init(w, h, holes); Sisco path = findPath(sectors[trip1 - 1], sectors[trip2 - 1]); dump(path, holes, names, out); } public static void main(String[] args) { parse("sisco.in", "sisco.out"); } }