본문 바로가기
알고리즘 문제

[알고리즘 문제] rook

by 박연호의 개발 블로그 2019. 4. 23.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int[][] ary = new int[8][8];
        boolean rightNeedToCheck = true, leftNeedToCheck = true, topNeedToCheck = true, bottomNeedToCheck = true; // 상,하,좌,우로
                                                                                                                  // 체크할
                                                                                                                  // 필요가
                                                                                                                  // 있는지
                                                                                                                  // 없는지
        int x = 0, y = 0; // 킹의 x,y위치
        int n;
        int result = 0; // 킹이 룩에게 잡힐 가능성이 있는지 없는지

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                n = sc.nextInt();
                if (n == 1) { // 킹의 위치를 확인
                    x = j;
                    y = i;
                    continue;
                }
                ary[i][j] = n;
            }
        }

        for (int i = 1; i <= 6; i++) { // 상,하,좌,우로 한칸씩 증가하면서 검사
            // 오른쪽 확인
            if (rightNeedToCheck && x + i < 8) { // 오른쪽으로 진행할 수 있고(rightNeedToCheck가 true), 배열에서 벗어나지 않으면
                if (ary[y][x + i] == 3) { // 기물이 먼저 나타나면 이후에 룩이 있어도 킹은 잡히지 않음. 그렇다면 오른쪽 방향은 잡힐 가능성이 없음
                    rightNeedToCheck = false;
                } else if (ary[y][x + i] == 2) { // 기물보다 룩이 먼저 나타나면 킹은 잡힐 가능성이 있다. result=1로 하고 for문을 빠져나온다
                    result = 1;
                    break;
                }
            }

            // 왼쪽 확인
            if (leftNeedToCheck && x - i >= 0) {
                if (ary[y][x - i] == 3) {
                    leftNeedToCheck = false;
                } else if (ary[y][x - i] == 2) {
                    result = 1;
                    break;
                }
            }

            // 위쪽 확인
            if (topNeedToCheck && y - i >= 0) {
                if (ary[y - i][x] == 3) {
                    topNeedToCheck = false;
                } else if (ary[y - i][x] == 2) {
                    result = 1;
                    break;
                }
            }

            // 아래쪽 확인
            if (bottomNeedToCheck && y + i < 8) {
                if (ary[y + i][x] == 3) {
                    bottomNeedToCheck = false;
                } else if (ary[y + i][x] == 2) {
                    result = 1;
                    break;
                }
            }
        }

        System.out.println(result);

    }
}

문제는 킹이 룩에게 잡힐 가능성이 있는지 없는지 검사하는 문제이다. 체스판에서 룩은 현재 위치에서 체스판에서 벗어나지 않는 가로/세로 방향으로 움직일 수 있다. 만약 룩이 가로/세로로 움직이는데 진행방향에 킹이 있다면 1을 출력, 그렇지 않고 킹과 룩 사이에 기물이 있다면 0을 출력하는 문제이다.

 

아이디어는 킹의 위치에서 좌/우/상/하 방향으로 1,2,3....6까지 진행을 하면서 만약 기물이 먼저 나타나면 그쪽 방향을 검사할 필요가 없다. 왜냐하면 나중에 룩이 나타나더라도 기물에 가로막혀 잡힐 가능성이 없기 때문이다.

 

네방향중에 오른쪽의 경우 킹의 위치에서 오른쪽 방향으로 1,2,3...6씩 진행하다가 만약 기물이 나타나면 rightNeedToCheck값을 false로 해준다. 그러면 다음 for문에서 오른쪽 방향을 진행하는 if문이 false가 되어 더이상 오른쪽은 검사하지 않게 된다. 그렇지 않고 만약 오른쪽 방향으로 진행하다가 기물보다 룩을 먼저 만날경우 이는 잡히게 된다. 그러면 result=1로 하고 for문을 탈출한다. 잡힐 가능성이 있기 때문에 더이상 검사할 필요가 없다.

'알고리즘 문제' 카테고리의 다른 글

[알고리즘 문제] 두 용액  (0) 2019.05.13
[알고리즘 문제] 나무 자르기  (0) 2019.05.03
[알고리즘 문제] division  (0) 2019.04.19
[알고리즘 문제] Mountain  (0) 2019.04.16
[알고리즘 문제] 문자열 압축  (0) 2019.04.15