Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.LinkedList;
- import java.util.Deque;
- import java.util.Queue;
- import java.util.Scanner;
- public class Safe {
- static class sequence_t {
- public sequence_t(int n, sequence_t p, char c, int a) {
- currNum = n;
- prev = p;
- code = c;
- action = a;
- }
- int currNum;
- char code; // U or D
- int action; // Digit moved
- sequence_t prev;
- }
- // Follow the links in a sequence ending at s, and display
- // the sequence
- static void print_sequence(sequence_t s, int codeLength, int depth) {
- LinkedList<String> out = new LinkedList<String>();
- while (s.prev != null) {
- out.addFirst(String.format("%s%d %0" + codeLength + "d", s.code, codeLength - s.action, s.currNum));
- depth++;
- s = s.prev;
- }
- System.out.println(depth);
- for (String move : out) {
- System.out.println(move);
- }
- }
- //Return number that results from taking the number in currNum,
- //moving digit specified by action, either 'U' or 'D' as determined
- //by value of c, for a code of length codeLength
- static int expandNode(int currNum, char c, int action, int codeLength) {
- int base;
- switch (action) {
- case 0:
- base = 1;
- break;
- case 1:
- base = 10;
- break;
- case 2:
- base = 100;
- break;
- case 3:
- base = 1000;
- break;
- case 4:
- base = 10000;
- break;
- case 5:
- base = 100000;
- break;
- case 6:
- base = 1000000;
- break;
- default:
- base = 10000000;
- break;
- }
- int digit = (currNum / base) % 10;
- // Special cases
- if (digit == 9 && c == 'U') {
- return currNum - 9 * base;
- }
- if (digit == 0 && c == 'D') {
- return currNum + 9 * base;
- }
- if (c == 'D') {
- return currNum - base;
- }
- return currNum + base;
- }
- //Direct Access Table that determines if numbers have already been visited
- static boolean[] prevNums;
- public static void main(String[] args) {
- // The start code and target
- int nStart, nTarget;
- Scanner sc = new Scanner(System.in);
- // Get start code and the code length
- String code;
- code = sc.next();
- int codeLength = code.length();
- prevNums = new boolean[(int) Math.pow(10, code.length())];
- nStart = Integer.valueOf(code);
- // Get end code
- nTarget = Integer.valueOf(sc.next());
- // Get forbidden codes
- while (sc.hasNext()) {
- prevNums[Integer.valueOf(sc.next())] = true;
- }
- // Immediately output -1 if start or target are forbidden
- if (prevNums[nStart] || prevNums[nTarget]) {
- System.out.println("-1");
- return;
- }
- // Store expanded nodes in a queue, so that we do a breadth first search of the code space
- Queue<sequence_t> Actions = new LinkedList<sequence_t>();
- // Put the start code in queue
- sequence_t state = new sequence_t(nStart, null, 'n', -1);
- prevNums[nStart] = true;
- Actions.add(state);
- // While there are items in the queue
- while (Actions.size() > 0) {
- // Grab front of queue
- sequence_t s = Actions.element();
- Actions.remove();
- // Expand the current node by storing all possible targets in the queue
- for (int i = 0; i < codeLength; i++) {
- for (int j = 0; j < 2; j++) {
- int n;
- if (j == 0) {
- n = expandNode(s.currNum, 'U', i, codeLength);
- } else {
- n = expandNode(s.currNum, 'D', i, codeLength);
- }
- if (!prevNums[n]) {
- sequence_t next;
- if (j == 0) {
- next = new sequence_t(n, s, 'U', i);
- } else {
- next = new sequence_t(n, s, 'D', i);
- }
- // If we have hit the target we're done
- if (n == nTarget) {
- print_sequence(next, codeLength, 0);
- return;
- }
- prevNums[n] = true;
- Actions.add(next);
- }
- }
- }
- }
- // The queue is empty, so we print out a -1
- System.out.println(-1);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement