티스토리 뷰

알고리즘/백준

백준 1986 (체스) - java

김다미김태리신시아 2023. 6. 16. 17:46

https://www.acmicpc.net/problem/1986

 

1986번: 체스

첫째 줄에는 체스 판의 크기 n과 m이 주어진다. (1 ≤ n, m ≤ 1000) 그리고 둘째 줄에는 Queen의 개수와 그 개수만큼의 Queen의 위치가 입력된다. 그리고 마찬가지로 셋째 줄에는 Knight의 개수와 위치,

www.acmicpc.net

평범한 구현문제이다. 퀸이 이동할 때 장애물을 만날 경우 해당 방향에 대한 이동이 불가하도록 boolean[] 배열을 사용하여 구현하였다.

나이트의 경우에는 그냥 좌표를 별도의 배열로 만들었다.

 

나이트의 이동 좌표 배열

static int[] kx = {-1,1,-1,1,-2,-2,2,2};
static int[] ky = {-2,2,2,-2,1,-1,1,-1};

 

퀸의 이동 로직

if(board[x][y]==1)
        {
            int idx = 1; // 퀸의 이동 칸수에는 제한이 없다 !
            boolean[] keep = new boolean[8]; // 각 방향에 대한 이동 가능 여부

            while(true)
            {
                for(int i=0;i<8;i++)
                {
                    if(keep[i])
                        continue; // 해당 방향으로 이동 불가능한 경우

                    int nx = x + idx*qx[i];
                    int ny = y + idx*qy[i];

                    if(nx<1||nx>n||ny<1||ny>m) {
                        keep[i] = true; // 좌표계를 벗어난 경우 (더이상 해당 방향으로 이동 불가능)
                        continue;
                    }

                    if(board[nx][ny]==-1 || board[nx][ny]==2) {
                        keep[i] = true; // 중간에 다른 기물을 만난 경우(퀸은 넘을 수 없다)
                        continue;
                    }
                    visit[nx][ny] = true;
                }

                int tmp = 0;
                for(int i=0;i<8;i++)
                {
                    if(keep[i])
                         tmp = tmp + 1; // 모든 방향이 이동 불가능한 경우
                }

                if(tmp==8)
                    break;

                else{
                    idx = idx + 1;
                }
            }
        }

 

전체코드

import java.io.*;
import java.util.*;

public class Main {

    static int n = 0;
    static int m = 0;


    static int[] qx  = {0,0,-1,1,1,1,-1,-1};
    static int[] qy = {1,-1,0,0,1,-1,-1,1};

    static int[] kx = {-1,1,-1,1,-2,-2,2,2};
    static int[] ky = {-2,2,2,-2,1,-1,1,-1};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());

        int[][] board = new int[n+1][m+1];
        boolean[][] visit = new boolean[n+1][m+1];

        st = new StringTokenizer(br.readLine(), " ");
        int num = Integer.parseInt(st.nextToken());
        for(int i=1;i<=num;i++)
        {
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());

            board[x][y] = 1; // Queen
        }

        st = new StringTokenizer(br.readLine(), " ");
        num = Integer.parseInt(st.nextToken());
        for(int i=1;i<=num;i++)
        {
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());

            board[x][y] = 2; // Knight
        }

        st = new StringTokenizer(br.readLine(), " ");
        num = Integer.parseInt(st.nextToken());
        for(int i=1;i<=num;i++)
        {
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());

            board[x][y] = -1; // Pawn
        }

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(board[i][j]==1||board[i][j]==2||board[i][j]==-1)
                    move(i,j,board,visit);
            }
        }

        System.out.println(count(visit));
        
        br.close();
    }
    static void print(boolean[][] visit)
    {
        for(int i=1;i<=n;i++) {
            for (int j = 1; j <= m; j++) {
                if(visit[i][j])
                {
                    System.out.print(1+" ");
                }
                else{
                    System.out.print(0+" ");
                }
            }
            System.out.println();
        }
        System.out.println();
    }
    static int count(boolean[][] visit)
    {
        int count = 0;

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(!visit[i][j])
                    count = count + 1;
            }
        }

        return count;
    }
    static void move(int x,int y,int[][] board,boolean[][] visit)
    {
        visit[x][y] = true;

        if(board[x][y]==1)
        {
            int idx = 1;
            boolean[] keep = new boolean[8];

            while(true)
            {
                for(int i=0;i<8;i++)
                {
                    if(keep[i])
                        continue;

                    int nx = x + idx*qx[i];
                    int ny = y + idx*qy[i];

                    if(nx<1||nx>n||ny<1||ny>m) {
                        keep[i] = true;
                        continue;
                    }

                    if(board[nx][ny]==-1 || board[nx][ny]==2) {
                        keep[i] = true;
                        continue;
                    }
                    visit[nx][ny] = true;
                }

                int tmp = 0;
                for(int i=0;i<8;i++)
                {
                    if(keep[i])
                         tmp = tmp + 1;
                }

                if(tmp==8)
                    break;

                else{
                    idx = idx + 1;
                }
            }
        }

        else if(board[x][y]==2)
        {
            for(int i=0;i<8;i++)
            {
                int nx = x + kx[i];
                int ny = y + ky[i];

                if(nx<1||nx>n||ny<1||ny>m)
                    continue;

                visit[nx][ny] = true;
            }
        }
    }
}