/** * Solution to "Once Around the Lock" * Any sequence of random moves could be performed prior to a * correct sequence that opens the lock, so the basic idea is to * work backwards (assuming a correct solution that has * "z" at the top), undoing all the turns. See if some suffix of * moves has the right properties to unlock the lock, then see if * undoing the rest of the moves puts the lock into a state with * zero at the top. */ import java.util.*; class Move { public String dir; // "C" or "CC" public int dist; public Move(String d, int ds) { dir = d; dist = ds; } public String toString() { return dir+" "+dist; } } public class BLock { public static Scanner in = new Scanner(System.in); public static int n, // number of positions on dial x,y,z; // combination public static ArrayList move; public static int caseNum; public static void main(String[] args) { caseNum = 0; while ((n = in.nextInt()) != 0) { caseNum++; x = in.nextInt(); y = in.nextInt(); z = in.nextInt(); move = new ArrayList(); String dir = in.next(); while (!dir.equals("?")) { int dist = in.nextInt(); move.add(new Move(dir,dist)); dir = in.next(); } //display(); boolean open = true; // Assume that z is at the top. The last group of rotations // must be a set of clockwise rotations that, summed together, // take y to z and add up to at most n, so we undo these by // making counterclockwise rotations: int i = move.size()-1; int sum = 0; while (i >= 0) { Move m = move.get(i); if (m.dir.equals("C")) { sum += m.dist; } else break; i--; } if (sum != (n+y-z)%n) { open = false; } else { // Assume y is at the top. Look for counterclockwise rotations // adding up to at least n, but less than 2n, that take x to y; // undo these by making clockwise rotations. sum = 0; while (i >= 0) { Move m = move.get(i); if (m.dir.equals("CC")) { sum += m.dist; } else break; i--; } if (sum != n + (n+y-x)%n) { open = false; } else { // Assuming x is at the top, look for a sequence of // clockwise rotations that, when undone, amount to at // least one full revolution. sum = 0; boolean found = false; while (i >= 0 && !found) { Move m = move.get(i); if (m.dir.equals("C")) { sum += m.dist; // see if at least one full revolution: if (sum >= n) { found = true; } } else break; i--; } if (!found) { open=false; } else { // Undo all the remaining moves and make sure that // 0 is still at the top. sum = 0; while (i >= move.size()) { Move m = move.get(i); if (m.dir.equals("C")) sum += m.dist; else sum += n-m.dist; i--; } if (sum%n != 0) open = false; } } } System.out.print("Case " + caseNum + ": "); if (open) System.out.println("Open"); else System.out.println("Closed"); } } public static void display() { System.out.printf("Case %d: %d %d %d %d\n",caseNum,n,x,y,z); for (Move m: move) { System.out.printf("%s %d ",m.dir,m.dist); } System.out.println(); } }