📕문제
8*8 크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는 행을 상징한다. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8이다. 예를 들어, 왼쪽 아래 코너는 A1이고, 그 오른쪽 칸은 B1이다.
킹은 다음과 같이 움직일 수 있다.
- R : 한 칸 오른쪽으로
- L : 한 칸 왼쪽으로
- B : 한 칸 아래로
- T : 한 칸 위로
- RT : 오른쪽 위 대각선으로
- LT : 왼쪽 위 대각선으로
- RB : 오른쪽 아래 대각선으로
- LB : 왼쪽 아래 대각선으로
체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.
입력으로 킹이 어떻게 움직여야 하는지 주어진다. 입력으로 주어진 대로 움직여서 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너뛰고 다음 이동을 한다.
킹과 돌의 마지막 위치를 구하는 프로그램을 작성하시오.
📕입력
첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.
📕출력
첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.
💡문제해석
- 첫 번째 입력은 킹의 좌표, 두 번째 입력은 돌의 좌표, 세 번째 입력은 움직이는 횟수이다.
- 한 줄로 입력받아서 이것을 공백 단위로 끊어줘서 각각 넣어줘야 한다.
- 나는 chess [0]이 킹, chess [1]이 돌, chess [2]가 움직이는 횟수이다.
- 한 줄로 입력받아서 이것을 공백 단위로 끊어줘서 각각 넣어줘야 한다.
- 그리고 방향을 입력받는다.
- 방향은 if문으로 해서 좌표로 이동시켜 주면 된다.
- 만약 움직였는데 돌의 좌표로 이동한다면 돌도 그때의 vertex대로 이동시켜주면 된다.
- 주의할 점은 킹과 돌이 움직였는데 체스판을 벗어난다면 움직이기 전 좌표로 다시 되돌아가야 한다.
- 여기서 경우의 수가 있다.
- 첫 번째 경우는 킹이 움직였는데 킹이 벗어나는 경우이다.
- 두 번째 경우는 킹이 움직였는데 돌과 같은 위치가 되어서 돌을 움직였는데, 돌이 체스판을 벗어난 경우다.
- 이 경우 돌을 원래 좌표로 이동시키는 것뿐만 아니라, 킹도 원래의 좌표로 이동시켜줘야 한다.
- 킹의 좌표는 Oldx, Oldy [예전 좌표] / Row, Col [현재 좌표]
- 돌의 좌표는 oldx, oldy [예전 좌표]/row, col [현재 좌표]
- 여기서 경우의 수가 있다.
- 그다음 int type로 지정된 Row, Col, row, col을 다시 chess좌표상의 문자로 바꿔준다.
/*
8X8 체스판. 알파벳은 열을 상징, 숫자는 행을 상징
가장 왼쪽 열은 A, 가장 오른쪽 열은 H
가장 아래 행은 1, 가장 위 행은 8이다.
방향은 8개가 있다.
이동을 못할 경우 건너뜀.
킹이 돌과 같은 곳으로 이동할 때 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킴.
킹, 돌 움직이는 횟수
움직이는 방향
*/
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int x, y,Oldx,Oldy,oldx,oldy; //Old x Old y 는 움직이기 전 킹좌표, oldx, oldy는 움직이ㅣㄱ 전 도로자표ㅕ
//정지는 없다.(0,0)제외
void location(char a, char b,int &row, int &col);
void move(string s, int &x, int &y);
string change(int row,int col);
int main()
{
int Row,Col,row,col; //Row,Col == 킹 , row,col= 돌
string s, word;
vector<string> chess;
int count;
getline(cin, s);
stringstream ss(s);
ss.str(s);
while (ss >> word)
{
chess.push_back(word);
}
// chess[0]이 현재 킹의 좌표.
// chess[1]이 돌 좌표
location(chess[0][0],chess[0][1],Row,Col); //킹의 좌표를 좌표상으로 표현함.
location(chess[1][0],chess[1][1],row,col); //돌의 좌표를 좌표상으로 표현함.
count = stoi(chess[2]);
//움직이는 횟수 정확하게 나옴.
for(int i=0; i<count;i++){
string vertex;
cin>>vertex; //방향 입력받고
Oldx=Row, Oldy=Col,oldx=row,oldy=col; //움직이기 전 좌표.
move(vertex,Row,Col); //방향대로 움직여줌.
if(Row==row && Col==col) // 움직엿는데 돌쪽으로 갔다면
{
move(vertex,row,col); //돌도 그 방향대로 움직임.
//여기서 만약 돌이 넘어가면 킹도 움직인걸 다시 물러야함.
if(row==oldx && col ==oldy){ //돌의 움직인 좌표가 예전과 같다면 못움직엿다는 뜻임.
Row=Oldx,Col=Oldy; //킹도 예전좌표로 돌려준다.
}
}
}
cout<<change(Row,Col)<<endl; //좌표를 다시 영어로 변환
cout<<change(row,col)<<endl; //좌표를 다시 영어로 변환
}
string change(int row,int col)
{
string s;
if(col==0){
s='A';
}
if(col==1){
s='B';
}
if(col==2){
s='C';
}
if(col==3){
s='D';
}
if(col==4){
s='E';
}
if(col==5){
s='F';
}
if(col==6){
s='G';
}
if(col==7){
s='H';
}
row=8-row;
row=row+48;
s+=row;
return s;
}
void location(char a, char b,int &row, int &col) //A1 등등 이런거
{
if(a=='A'){
col=0;
}
if(a=='B'){
col=1;
}
if(a=='C'){
col=2;
}
if(a=='D'){
col=3;
}
if(a=='E'){
col=4;
}
if(a=='F'){
col=5;
}
if(a=='G'){
col=6;
}
if(a=='H'){
col=7;
}
//row=8-(int)b; //1은 index 7 row 8은 index 0
b=b-48;
row=8-b;
}
void move(string str, int &x, int &y)
{
int oldx,oldy;
oldx=x,oldy=y;
if (str == "L")
{
x += 0, y += -1;
}
else if (str == "R")
{
x += 0, y += 1;
}
else if (str == "T")
{
x = x - 1, y += 0;
}
else if (str == "B")
{
x = x + 1, y += 0;
}
else if (str == "RT")
{
x = x - 1, y += 1;
}
else if (str == "LT")
{
x = x - 1, y = y - 1;
}
else if (str == "RB")
{
x = x + 1, y = y + 1;
}
else if (str == "LB")
{
x = x + 1, y = y - 1;
}
if(x <0 || x>7 || y<0 || y>7) // 만약 체스판이 넘어간다면 원래 좌표를 넣어줌.
{
x=oldx,y=oldy;
}
}
주석을 그래도 나름 자세하게 달았다고 생각해서 이해 안 되는 것은 주석을 보면 이해가 될 것 같다
느낀 점
- 문자열로 입력받은 좌표를 행렬 상으로 바꿔줄 때가 너무 귀찮았다.
- 더 똑똑한 방법이 있었을까?라고 생각해 봤지만 너무 복잡해서 그냥 이렇게 했다.
'CodingTest > Baekjoon' 카테고리의 다른 글
[백준 11053]-가장 긴 증가하는 부분 수열(C++) (0) | 2022.07.06 |
---|---|
[백준 12865]-평범한 배낭(C++) (0) | 2022.07.06 |
[백준 1059] 좋은구간(C++) (0) | 2022.07.05 |
[백준 1057] 토너먼트(C++) (0) | 2022.06.26 |
[백준 16563] 어려운 소인수분해 구하기 (C++) (0) | 2022.06.10 |