본문 바로가기
  • 기억의 유한함을 기록의 무한함으로✍️            예비 개발자가 꿈꾸는 공간 여기는 안나의 개발 블로그 💻
Algorithm/PS - 백준

[백준 Java] 1063번 킹 (구현, 시뮬레이션)

by 제가안난데여♪(´ε`*) 2023. 6. 18.
728x90

 

[Silver III] 킹 - 1063

문제 링크

성능 요약

메모리: 11596 KB, 시간: 80 ms

분류

구현, 시뮬레이션

문제 설명

8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는 행을 상징한다. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8이다. 예를 들어, 왼쪽 아래 코너는 A1이고, 그 오른쪽 칸은 B1이다.

킹은 다음과 같이 움직일 수 있다.

  • R : 한 칸 오른쪽으로
  • L : 한 칸 왼쪽으로
  • B : 한 칸 아래로
  • T : 한 칸 위로
  • RT : 오른쪽 위 대각선으로
  • LT : 왼쪽 위 대각선으로
  • RB : 오른쪽 아래 대각선으로
  • LB : 왼쪽 아래 대각선으로

체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.

입력으로 킹이 어떻게 움직여야 하는지 주어진다. 입력으로 주어진 대로 움직여서 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너 뛰고 다음 이동을 한다.

킹과 돌의 마지막 위치를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.

출력

첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.

풀이

이동한 킹의 위치가 체스판을 벗어나는지 확인

벗어난다면 그 이동은 건너 뛴다.

벗어나지 않는다면 이동한 킹의 위치가 이동하지 않은 돌의 위치와 같은지 확인

같지않다면 킹만 이동을 확정함

같다면 돌을 이동 시킴

이동한 돌의 위치가 체스판을 벗어나는지 확인

벗어난다면 킹도 돌도 그 이동은 건너뛴다.

벗어나지 않는다면 킹과 돌의 이동을 확정함

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	static class Point {
		int row;
		int col;

		public Point(int row, int col) {
			super();
			this.row = row;
			this.col = col;
		}
	}

	static Point king;
	static Point stone;
	static int N;
	static int dir[][] = {{0, 1},{0,-1},{1,0},{-1,0},{-1,1},{-1,-1},{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());

		String kingPoint = st.nextToken();
		String stonePoint = st.nextToken();
		N = Integer.parseInt(st.nextToken());

		//문제에서 제기된 좌표위치 방식을 좌측 상단이 0,0 우측하단이 r,c 가 되도록 변경
		int row = 8-((int) kingPoint.charAt(1)-48);
		int col = (int) kingPoint.charAt(0) - 65;
		king = new Point(row, col);

		row = 8-((int) stonePoint.charAt(1)-48);
		col = (int) stonePoint.charAt(0) - 65;
		stone = new Point(row, col);

		for (int i = 0; i < N; i++) {
			String op = br.readLine();
			int d = -1;
			switch (op) {
			case "R": {
				d = 0;
				break;
			}
			case "L": {
				d = 1;
				break;
			}
			case "B": {
				d = 2;
				break;
			}
			case "T": {
				d = 3;
				break;
			}
			case "RT": {
				d = 4;
				break;
			}
			case "LT": {
				d = 5;
				break;
			}
			case "RB": {
				d = 6;
				break;
			}
			case "LB": {
				d = 7;
				break;
			}
			}
			
			//명령어를 실행한 후 이동된 king의 위치를 미리 저장
			int krow = king.row+dir[d][0];
			int kcol = king.col+dir[d][1];
			if(isRange(krow, kcol)) { //체스판을 벗어나는지 확인
				if(krow == stone.row && kcol == stone.col) { //이동한 킹의 위치가 돌의 위치와 같을때 돌의 위치를 이동시켜야함
					int srow = stone.row+dir[d][0];
					int scol = stone.col+dir[d][1];
					if(isRange(srow, scol)) { //돌의 위치가 체스판을 벗어난다면 킹도 돌도 이동시키지 않음
//						System.out.println("둘다 바뀜");
						king.row = krow;
						king.col = kcol;
						stone.row = srow;
						stone.col = scol;
					}else {
//						System.out.println("돌이 범위를 넘어서 패스");
					}
				}else {
//					System.out.println("킹만 바뀜");
					king.row = krow;
					king.col = kcol;
				}
			}else {
//				System.out.println("킹이 범위를 넘어서 패스");
			}
		}
		
		StringBuilder sb = new StringBuilder();
		sb.append((char)(king.col+65)).append(8-king.row).append("\n");
		sb.append((char)(stone.col+65)).append(8-stone.row).append("\n");
		System.out.println(sb.toString());
	}

	private static boolean isRange(int r, int c) {
		return r >=0 && r < 8 && c >=0 && c < 8;
	}

}
반응형