코드트리에서 위의 문제를 푼 과정을 기록해보도록 하겠습니다!
문제는 조금 복잡한 구현 느낌의 문제였습니다!
코드 트리는 주제를 먼저 던져주고 해당 주제 내에서 개념-문제로 이어지는 학습을 진행했기 때문에 문제 풀이 방법을 쉽게 떠올릴 수 있었습니다.
풀이 과정은 크게 다음과 같이 진행했습니다.
이러한 순서로 구현을 완료했습니다!
아래는 구현한 코드입니다.
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;
}
}
최대한 코드의 구현 흐름을 알아보기 쉽게 하기 위해 각 과정별로 메소드 분리를 진행했습니다.
(맵 이동 메소드, 위아래 전파 가능한지 알아보는 메소드)
이때 처음에 실수했던 부분은 다음과 같습니다.
이 부분은 다음과 같이 위아래 전파 시에 상태를 새로 초기화해줘서 처리했습니다.
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");
구현이 간단했던 것 같지만 조금 헷갈리던 부분도 있었던 것 같습니다 :)
구현 문제는 확실히 문제를 천천히 보면서 처음에 분석하는 것이 중요한 것 같습니다!