백준 1063번 구현 문제를 Java로 풀어보았다. 처음에는 맞긴 했지만 불필요한 짓을 아주 길게도 했고, 뭔가 이상하다 싶어서 다시 코드를 더 간단하게 만들어봤다. 무슨 삽질을 했는지 살펴보자.
문제 링크만 첨부해두겠다.
https://www.acmicpc.net/problem/1063
내가 이 문제를 풀며 했던 삽질은 내 습관적인 풀이를 버리지 못해서, 문제 조건대로 풀지 못하고 내 식대로 바꿔야만 직성이 풀리는 쪼다같은 성격으로부터 기인한다.
문제 조건은 map[0][1]
과 같은 형식이 아닌 A1
, B8
과 같은 형식으로 주어진다. 여지껏 풀어왔던 문제들은 모두 보편적인 이차원 배열이었지만 여기서는 이 문제만의 고유한 표기 방식을 사용했다.
하지만 여기서 초점은 결국 한 칸씩 이동할 때 row와 col이 +1,-1 이 된다는 점은 달라지지 않는다는 사실이다. 그런데 굳이 내가 그동안 풀어왔던 익숙한 방식으로 풀겠다고 굳이 변환 메소드를 만드는 개뻘짓을 한 것이다.
아래 코드는 좌표 ->문제 표기방식
과 문제 표기방식 -> 좌표
를 수행하는 메소드를 작성한 것이다.
static Pos chessToMap(String pos){
Pos position;
char chessCol = pos.charAt(0);
char chessRow = pos.charAt(1);
int mapRow; int mapCol;
mapRow = Math.abs(Character.getNumericValue(chessRow)-8);
mapCol = Character.getNumericValue(chessCol) - 10;
position = new Pos(mapRow, mapCol);
return position;
}
static String posToChess(Pos a){
int row = Math.abs(a.row-8);
int col = a.col + 65;
char cCol = (char) col;
return String.valueOf(cCol) + String.valueOf(row);
}
어차피 한 칸씩만 이동한다는 원리는 동일한데 대체 왜 짠 거지? 진짜 개뻘짓이다. ㅆ...
결국 한 칸씩만 이동해주면 되는 것이다!!!
아래는 명령어와 그에 따라 위치를 옮겨주는 메소드다.
static char[] move(String cmd, char[] target){
char[] result = target.clone();
switch(cmd){
case "R":
result[0]++;
break;
case "L":
result[0]--;
break;
case "B":
result[1]--;
break;
case "T":
result[1]++;
break;
case "RT":
result[0]++; result[1]++;
break;
case "LT":
result[0]--; result[1]++;
break;
case "RB":
result[0]++; result[1]--;
break;
case "LB":
result[0]--; result[1]--;
}
return result;
}
이렇게 간단한 것을...
아래는 내가 제출한 코드다.
import java.util.*;
import java.io.*;
public class boj1063 {
static char[] king, rock;
static int n;
public static void main(String args[]) throws IOException {
BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer stk = new StringTokenizer(bfr.readLine()," ");
king = stk.nextToken().toCharArray(); rock = stk.nextToken().toCharArray(); n = Integer.parseInt(stk.nextToken());
for(int i=0; i<n; i++) {
String cmd = bfr.readLine();
char[] next_king = move(cmd, king);
if(isInRange(next_king)){ // 킹 움직였더니 일단 범위 안에는 있음
if(next_king[0]==rock[0] && next_king[1]==rock[1]){ // 킹 움직였더니 돌이랑 겹치면
char[] next_rock = move(cmd,rock);
if(isInRange(next_rock)){ // 움직인 돌도 범위 안에 있으면
king = next_king;
rock = next_rock;
}
else continue; // 돌이 범위 밖으로 나가면 이번 명령 무시
}
else{ // 킹 움직였더니 돌이랑 겹치진 않으면 킹만 움직이면 됨
king = next_king;
}
}
else continue; // 킹 움직였더니 범위 밖으로 나가면 명령 무시
}
bfw.write(String.valueOf(king[0]) + String.valueOf(king[1]) + "\n");
bfw.write(String.valueOf(rock[0]) + String.valueOf(rock[1]));
bfw.close();
}
static Boolean isInRange(char[] a){
if(a[0]<'A' || a[0]>'H' || a[1]<'1' || a[1]>'8') return false;
else return true;
}
static char[] move(String cmd, char[] target){
char[] result = target.clone();
switch(cmd){
case "R":
result[0]++;
break;
case "L":
result[0]--;
break;
case "B":
result[1]--;
break;
case "T":
result[1]++;
break;
case "RT":
result[0]++; result[1]++;
break;
case "LT":
result[0]--; result[1]++;
break;
case "RB":
result[0]++; result[1]--;
break;
case "LB":
result[0]--; result[1]--;
}
return result;
}
}
개뻘짓을 해도 맞기는 맞다. ㅎ
오늘 배운 것
- 내가 편한 풀이만 고집하지 말자
- 문제에서 준 조건 그대로를 코드로 옮겨보려 노력하자