import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { static int length=0; int numVertices = 0; int sourceX=0; int sourceY=0; int targetX=length; int targetY=length; int distance=0; int numPossible=0; static Node targetNode; //static HashMap alreadyHit; static boolean debug=false; static class Node{ int xCoord; int yCoord; Node parent; int moveCount; HashMap alreadyHit; boolean visited; public Node(int x, int y, Node p){ xCoord = x; yCoord = y; parent = p; if (parent == null){ moveCount = 0; alreadyHit = new HashMap(); } else { moveCount = parent.moveCount + 1; //alreadyHit=parent.alreadyHit; Node tempParent = parent; alreadyHit = new HashMap(); while(tempParent != null){ this.alreadyHit.put(tempParent.getTag(), true); tempParent = tempParent.parent; } } } public int getXCoord(){ return xCoord; } public int getYCoord(){ return yCoord; } public String getTag(){ return xCoord + "," + yCoord; } public void addNodeToHistory(String str){ alreadyHit.put(str, true); } public boolean isNodeInHistory(String str){ return alreadyHit.containsKey(str); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); //int n = 10; // your code goes here length=n-1; //numVertices = n*n; targetNode = new Node(length, length, null); // knight shape loop for(int x=1; x(); return endNode.moveCount; } static Node getShortestPathToEndNode(Node rootNode, int moveByX, int moveByY) { if (checkNode(rootNode)){ return rootNode; } //alreadyHit.put(rootNode.getTag(), true); HashMap neighborMap = new HashMap(); rootNode.addNodeToHistory("0,0"); ArrayList neighbors = new ArrayList<>(); ArrayList tempList = new ArrayList<>(); ArrayList tempForAdding = new ArrayList<>(); neighbors.add(rootNode); boolean foundTarget=false; Node nodeToReturn = new Node(0,0,null); if (debug){ //System.out.println("debugging"); } while(neighbors.size()>0 && !foundTarget) { tempForAdding.clear(); for(int j=0; j newNeighbors = new ArrayList<>(); int numNewNeighbors = numPossibleMoves(currNode, moveByX, moveByY,newNeighbors); if (numNewNeighbors == 0){ neighbors.clear(); tempList.clear(); nodeToReturn.moveCount=-1; if (tempForAdding.size()==0){ return nodeToReturn; } else { neighbors.clear(); neighbors.addAll(tempForAdding); } } if (numNewNeighbors>0){ for(int x=0; x < numNewNeighbors; x++){ Node neighborNode = newNeighbors.get(x); //System.out.println("move by: " +moveByX+","+moveByY+ " neighbor: " + neighborNode.getTag()); if (checkNode(neighborNode)){ foundTarget = true; nodeToReturn = neighborNode; tempList.clear(); neighbors.clear(); return nodeToReturn; } if (!neighborMap.containsKey(newNeighbors.get(x).getTag())){ tempList.add(newNeighbors.get(x)); neighborMap.put(newNeighbors.get(x).getTag(), 0); } } tempForAdding.addAll(tempList); } } neighbors.clear(); neighbors.addAll(tempForAdding); } if (!foundTarget){ nodeToReturn.moveCount=-1; } return nodeToReturn; } // public void mainLoop(LinkedList queue, Node node){ // queue.add(node); // node.visited=true; // boolean foundTarget=false; // while (!queue.isEmpty()) // { // // Node element = queue.remove(); // System.out.print(element.data + "\t"); // ArrayList neighbours=findNeighbours(adjacency_matrix,element); // for (int i = 0; i < neighbours.size(); i++) { // Node n=neighbours.get(i); // if(n!=null && !n.visited) // { // queue.add(n); // n.visited=true; // // } // } // // } // } // returns true if we are at the target static boolean checkNode(Node a){ if (a.getXCoord() == targetNode.getXCoord()){ if (a.getYCoord() == targetNode.getYCoord()){ return true; } else{ return false; } } else { return false; } } public static int numPossibleMoves(Node currNode, int moveX, int moveY, ArrayList neighborNodes){ int moves=0; int potentialX = (currNode.getXCoord() + moveX); int potentialY = (currNode.getYCoord() + moveY); // if (!alreadyHit.containsKey(new Node(potentialX, potentialY, currNode.parent).getTag())){ // moves++; // neighborNodes.add(new Node(potentialX, potentialY, currNode)); // alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); // } // +x, +y if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // +x, +y (swap) potentialX = (currNode.getXCoord() + moveY); potentialY = (currNode.getYCoord() + moveX); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // +x, -y potentialX = (currNode.getXCoord() + moveX); potentialY = (currNode.getYCoord() - moveY); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // +x, -y (swap) potentialX = (currNode.getXCoord() + moveY); potentialY = (currNode.getYCoord() - moveX); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // -x, -y potentialX = (currNode.getXCoord() - moveX); potentialY = (currNode.getYCoord() - moveY); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // -x, -y (swap) potentialX = (currNode.getXCoord() - moveY); potentialY = (currNode.getYCoord() - moveX); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // -x, +y potentialX = (currNode.getXCoord() - moveX); potentialY = (currNode.getYCoord() + moveY); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } // -x, +y (swap) potentialX = (currNode.getXCoord() - moveY); potentialY = (currNode.getYCoord() + moveX); if (validPosition(potentialX, potentialY)){ if (!currNode.isNodeInHistory(new Node(potentialX, potentialY, currNode.parent).getTag())){ moves++; neighborNodes.add(new Node(potentialX, potentialY, currNode)); currNode.addNodeToHistory(new Node(potentialX, potentialY, currNode.parent).getTag()); //alreadyHit.put(new Node(potentialX, potentialY, currNode.parent).getTag(), true); } } return moves; } public static boolean validPosition(int x, int y){ if ((x>=0) && (x<=length)){ if ((y>=0) && (y<=length)){ return true; } return false; } return false; } }