[백준 C++] 1063 킹

이성훈·2022년 3월 3일
0

문제

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

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

R : 한 칸 오른쪽으로
L : 한 칸 왼쪽으로
B : 한 칸 아래로
T : 한 칸 위로
RT : 오른쪽 위 대각선으로
LT : 왼쪽 위 대각선으로
RB : 오른쪽 아래 대각선으로
LB : 왼쪽 아래 대각선으로
체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.

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

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

입력

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

출력

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

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

풀이

먼저, 킹과 돌의 위치를 (x, y) = (행, 열) 로 나타내자.
체스판의 행은 숫자1부터 역순으로 되있고
열은 A부터 H까지로 되있으므로
처음 입력값을 받을때 열은 문자이므로 적당한 아스키코드값을 빼며,
행은 역순이므로 7 - (구한값)으로 저장해야한다.
출력시에도 변환해야함.

먼저 현재 킹의위치 X,Y 변수 돌의 위치 X,Y변수를 입력받아 초깃값으로 넣는다. 이때 좌상단이 0,0 우하단이 7,7 이되는 좌표로 변환하여 넣는다.

다음으로 입력받은 이동횟수만큼 반복한다.
명령어(R, L ~ )를 문자열로 받아들이되 줄바꿈문자전까지 받아들이도록 정규표현식을 사용한다.
그리고 줄바꿈문자를 지워야하므로 temp라는 변수로 읽어들인다.

여기서 flag는
1~8의값으로 각 명령어와 대응되는 값이다.

이제 첫번째로 킹의 다음 위치를 계산한다.
여기서 kX, kY는 다음 킹의 위치를 기록할 변수.

두번째로 돌과 킹이 겹쳤다면 돌을 움직인다. 이때 flag변수가 쓰인다

여기서도 sX, sY는 다음 돌의 위치를 기록할 변수

마지막으로 문제에서 킹과 돌이 체스판을 벗어나면 무시한다했으므로

(0, 0) ~ (7, 7) 좌표에서 벗어난값이면 현재위치를 갱신X 정상범주면 현재위치를 갱신한다.

총 n회 반복후 최종적인 킹과 돌의 위치를 출력한다.
이때 행은 역순으로 열은 문자로 출력해준다.

#define _CRT_SECURE_NO_WARNINGS 
#include <bits/stdc++.h>

void printAll(int a, int b) {
	int x = 8 - a;
	char y = b + 65;
	printf("%c%d \n", y, x);
}

int main(void) {
	int kingX, kingY, stoneX, stoneY, n;
	char init_kingY, init_kingX, init_stoneY, init_stoneX;
	scanf("%c%c %c%c %d\n", &init_kingY, &init_kingX, &init_stoneY, &init_stoneX, &n);
	kingX = 7 - (init_kingX - 49);
	kingY = init_kingY - 65;
	stoneX = 7 - (init_stoneX - 49);
	stoneY = init_stoneY - 65;
	char c[3], temp;

	while (n--) {
		scanf("%[^\n]s", &c); //명령어를 읽어들임.
		scanf("%c", &temp); //줄바꿈문자 제거
		//방향을 기억할 변수
		int flag = 0;
		//새로옮겨질 킹, 돌위치
		int kX=kingX, kY=kingY, sX=stoneX, sY=stoneY; 
		//킹을 움직이고 움직인 방향flag을 기록
		if (c[0] == 'R' && c[1] == '\0') {
			flag = 1;
			kY++;
		}
		else if (c[0] == 'L' && c[1] == '\0') {
			flag = 2;
			kY--;
		}
		else if (c[0] == 'B' && c[1] == '\0') {
			flag = 3;
			kX++;
		}
		else if (c[0] == 'T' && c[1] == '\0') {
			flag = 4;
			kX--;
		}
		else if (c[0] == 'R' && c[1] == 'T') {
			flag = 5;
			kX--;
			kY++;
		}
		else if (c[0] == 'L' && c[1] == 'T') {
			flag = 6;
			kX--;
			kY--;
		}
		else if (c[0] == 'R' && c[1] == 'B') {
			flag = 7;
			kX++;
			kY++;
		}
		else if (c[0] == 'L' && c[1] == 'B') {
			flag = 8;
			kX++;
			kY--;
		}

		//돌과 킹이겹쳤다면 돌을 움직임
		if (sX == kX && sY == kY) {
			switch (flag) {
			case 1:
				sY++;
				break;
			case 2:
				sY--;
				break;
			case 3:
				sX++;
				break;
			case 4:
				sX--;
				break;
			case 5:
				sX--;
				sY++;
				break;
			case 6:
				sX--;
				sY--;
				break;
			case 7:
				sX++;
				sY++;
				break;
			case 8:
				sX++;
				sY--;
				break;
			}
		}

		//돌또는 킹이 체스판밖으로 나갔는지 확인
		if (sX == -1 || sX == 8 ||
			sY == -1 || sY == 8 ||
			kX == -1 || kX == 8 ||
			kY == -1 || kY == 8) {
		}
		else {
			kingX = kX;
			kingY = kY;
			stoneX = sX;
			stoneY = sY;
		}

	}
	printAll(kingX, kingY);
	printAll(stoneX, stoneY);

	return 0;
}
profile
I will be a socially developer

0개의 댓글