[코드트리 조별과제] 1차원 바람 (격자 안에서 밀고 당기기)

KSH·2024년 7월 17일
0

1차원 바람 문제 링크

코드트리에서 위의 문제를 푼 과정을 기록해보도록 하겠습니다!

문제는 조금 복잡한 구현 느낌의 문제였습니다!

코드 트리는 주제를 먼저 던져주고 해당 주제 내에서 개념-문제로 이어지는 학습을 진행했기 때문에 문제 풀이 방법을 쉽게 떠올릴 수 있었습니다.

풀이 과정은 크게 다음과 같이 진행했습니다.

  1. 건물(맵) 상태, 방향 맵 초기화
  2. 바람에 따라 이동
    2-1. 위로 전파 가능할 때까지 위로 전파
    2-2. 아래로 전파 가능할 때까지 아래로 전파

이러한 순서로 구현을 완료했습니다!
아래는 구현한 코드입니다.

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

public class Main {

    static int N, M, Q;
    static int[][] map;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer input = new StringTokenizer(br.readLine());

        N = Integer.parseInt(input.nextToken());
        M = Integer.parseInt(input.nextToken());
        Q = Integer.parseInt(input.nextToken());

        // 전파 방향 맵
        Map<String, String> waveDirection = new HashMap<>();
        waveDirection.put("L", "R");
        waveDirection.put("R", "L");

        // 맵 초기화
        map = new int[N][M];
        for (int i = 0; i < N; i++) {
            StringTokenizer status = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(status.nextToken());
            }
        }

        // 바람에 따라 이동
        for (int i = 0; i < Q; i++) {
            StringTokenizer wind = new StringTokenizer(br.readLine());
            int row = Integer.parseInt(wind.nextToken()) - 1;
            String direction = wind.nextToken();
            moveMap(row, direction);

            int upRow = row;
            String upDirection = direction;
            int downRow = row;
            String downDirection = direction;
       
            // 위로 전파
            while (canUpWave(upRow)) {
                upRow--;
                upDirection = waveDirection.get(upDirection);
                moveMap(upRow, upDirection);
            }

            // 아래로 전파
            while (canDownWave(downRow)) {
                downRow++;
                downDirection = waveDirection.get(downDirection);
                moveMap(downRow, downDirection);
            }
        }

        for (int i = 0; i < N; i++) {
            int[] rowMap = map[i];
            for (int status : rowMap) {
                System.out.print(status + " ");
            }
            System.out.println();
        }
    }

    private static void moveMap(int row, String direction) {
        int[] target = map[row];
        if (direction.equals("L")) {
            int temp = target[M - 1];
            for (int i = M - 1; i >= 1; i--) {
                map[row][i] = target[i - 1];
            }
            map[row][0] = temp;
        }
        if (direction.equals("R")) {
            int temp = target[0];
            for (int i = 0; i < M - 1; i++) {
                map[row][i] = target[i + 1];
            }
            map[row][M - 1] = temp;
        }
    }

    private static boolean canUpWave(int row) {
        int targetRow = row - 1;
        if (targetRow < 0) {
            return false;
        }
        
        for (int i = 0; i < M; i++) {
            int status1 = map[row][i];
            int status2 = map[targetRow][i];
            if (status1 == status2) {
                return true;
            }
        }

        return false;
    }

    private static boolean canDownWave(int row) {
        int targetRow = row + 1;
        if (targetRow >= N) {
            return false;
        }

        for (int i = 0; i < M; i++) {
            int status1 = map[row][i];
            int status2 = map[targetRow][i];
            if (status1 == status2) {
                return true;
            }
        }

        return false;


    }
}

최대한 코드의 구현 흐름을 알아보기 쉽게 하기 위해 각 과정별로 메소드 분리를 진행했습니다.
(맵 이동 메소드, 위아래 전파 가능한지 알아보는 메소드)

이때 처음에 실수했던 부분은 다음과 같습니다.

  • 바람에 의해 이동한 row, direction을 전파 시에도 사용해서 에러

이 부분은 다음과 같이 위아래 전파 시에 상태를 새로 초기화해줘서 처리했습니다.

int upRow = row;
String upDirection = direction;
int downRow = row;
String downDirection = direction;

또, 방향을 반대로 지정할 때 단순히 if문을 사용하는게 좋지 않다고 생각들어서 간단히 Map을 사용하여 전환을 진행했습니다.

// 전파 방향 맵
Map<String, String> waveDirection = new HashMap<>();
waveDirection.put("L", "R");
waveDirection.put("R", "L");

구현이 간단했던 것 같지만 조금 헷갈리던 부분도 있었던 것 같습니다 :)
구현 문제는 확실히 문제를 천천히 보면서 처음에 분석하는 것이 중요한 것 같습니다!

profile
성실히 살아가는 비전공자

0개의 댓글