백준 1063번( 자바 )

Flash·2022년 1월 19일
0

BOJ-Algorithm

목록 보기
33/51
post-thumbnail

구현

백준 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;
    }
}


개뻘짓을 해도 맞기는 맞다. ㅎ

오늘 배운 것

  1. 내가 편한 풀이만 고집하지 말자
  2. 문제에서 준 조건 그대로를 코드로 옮겨보려 노력하자
profile
개발 빼고 다 하는 개발자

0개의 댓글