티스토리 뷰
728x90
반응형
Backtracking (되추적)
말이 존나어려운데 쉽게 말하면
어떤 노드의 유망성 점검후 유망하지않으면 그 노드의 부모 노드로 되돌아간다
예를들면 어떤길을 따라 쭉 가는데 길이 막혀있으면 마지막으로 만났던 갈림길로 되돌아가서 다른길로 가는거를 생각하면 되겠다.
Stack을 이용
자세한글은 https://idea-sketch.tistory.com/29 이분의 글을 참조
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | import java.util.Scanner; import java.util.Stack; class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } public class Main { public static void main(String[] args) { int chessBoardSize = inputValueScanner(); int[][] chessBoard = makeChessBoard(chessBoardSize); Stack<Integer> hopefulPointStack = new Stack<>(); int chessBoardLen = chessBoard[0].length; int n_QueenPlaceCount = 0; firstHopefulPointInsert(hopefulPointStack, chessBoardLen); first:while( !hopefulPointStack.isEmpty() ){ int hopefulPointX = hopefulPointStack.pop(); int hopefulPointY = hopefulPointStack.pop(); Point hopefulPoint = new Point(hopefulPointX, hopefulPointY); chessBoard[hopefulPointX][hopefulPointY] = hopefulPointX + 1; boolean checkPlaceableQueenSeat = false; for(int queenCount = hopefulPointX; queenCount < chessBoardLen;){ setLeftBottomDiagonalXvalueOfChessBoard(hopefulPoint, chessBoard); setCenterBottomStraightXvalueOfChessBoard(hopefulPoint, chessBoard); setRightBottomDiagonalXvalueOfChessBoard(hopefulPoint, chessBoard); queenCount++; // 퀸을 각 줄에 1개씩 다놓았을때 if( queenCount == chessBoardLen){ n_QueenPlaceCount++; // 체스판 초기화 코드 넣어야함 if(!hopefulPointStack.isEmpty()){ resetFlagIfUnplaceableQueen(hopefulPointStack.peek(), chessBoard); } break; } for(int y = chessBoardLen - 1; y >= 0; y--){ // 다음줄에 퀸을 놓을수있는지 확인 if( chessBoard[queenCount][y] == 0){ checkPlaceableQueenSeat = true; hopefulPointStack.push(y); hopefulPointStack.push(queenCount); } } // 퀸을 놓을자리가 없다면 if(!checkPlaceableQueenSeat){ if(!hopefulPointStack.isEmpty()){ resetFlagIfUnplaceableQueen(hopefulPointStack.peek(), chessBoard); } } break; } } System.out.println(n_QueenPlaceCount); } public static int inputValueScanner(){ Scanner scan = new Scanner(System.in); return scan.nextInt(); } public static int[][] makeChessBoard(int chessBoardSize){ return new int[chessBoardSize][chessBoardSize]; } public static void firstHopefulPointInsert(Stack<Integer> hopefulPointStack, int chessBoardLen){ for(int i = chessBoardLen - 1; i >= 0; i--){ hopefulPointStack.push(i); hopefulPointStack.push(0); } } public static void setLeftBottomDiagonalXvalueOfChessBoard(Point hopefulPoint, int[][] chessBoard){ int hopefulPointX = hopefulPoint.getX(); int minusYvalueContain = hopefulPoint.getY(); for(int x = hopefulPointX; (x + 1) < chessBoard[0].length; x++){ for(int y = minusYvalueContain; (y - 1) >= 0;){ if( chessBoard[x+1][y-1] == 0){ chessBoard[x+1][y-1] = hopefulPointX + 1; } minusYvalueContain = y-1; break; } } } public static void setCenterBottomStraightXvalueOfChessBoard(Point hopefulPoint, int[][] chessBoard){ int hopefulPointY = hopefulPoint.getY(); int hopefulPointX = hopefulPoint.getX(); for(int x = hopefulPoint.getX(); (x + 1) < chessBoard[0].length; x++){ if( chessBoard[x+1][hopefulPointY] == 0){ chessBoard[x+1][hopefulPointY] = hopefulPointX + 1; } } } public static void setRightBottomDiagonalXvalueOfChessBoard(Point hopefulPoint, int[][] chessBoard){ int hopefulPointX = hopefulPoint.getX(); int plusYvalueContain = hopefulPoint.getY(); for(int x = hopefulPointX; (x + 1) < chessBoard[0].length; x++){ for(int y = plusYvalueContain; (y + 1) < chessBoard[0].length;){ if( chessBoard[x+1][y+1] == 0){ chessBoard[x+1][y+1] = hopefulPointX + 1; } plusYvalueContain = y + 1; break; } } } public static void resetFlagIfUnplaceableQueen(int flagValue, int[][] chessBoard){ for(int x = flagValue; x < chessBoard[0].length; x++){ for(int y = 0; y < chessBoard[0].length; y++){ if( chessBoard[x][y] > flagValue){ // 다시 처음부터 해야한다면 다지워야하니 값보다 큰건 다지움 chessBoard[x][y] = 0; } } } } } | cs |
위 코드의 핵심은 Stack이다.
스택안에 유망한 노드의 좌표를 넣어서 막힐때마다 스택안의 값을 꺼내어 다시 계산한다
최대한 클린코드가 말한대로 나름 신경써서 코드를 작성했기에
먼 미래의 내가 볼때도 제발 무리가 없길 바란다.
728x90
반응형
'BAEKJOON' 카테고리의 다른 글
[10974] 모든 순열 (0) | 2019.07.22 |
---|
댓글