알고리즘/백준
[BOJ] 12100 - 2048 (Easy) (Java)
DeveloperJason
2023. 8. 17. 11:15
접근법
진짜 빡구현이란 이런 것이다..
디버깅이 헬이었던 문제
최적화가 필요할 것 같다
참고한 테스트케이스 첨부하겠음
#TC 1
input:
4
2 16 16 0
32 16 4 1
4 16 32 0
2 0 8 8
correct answer: 128
output: 64
#TC 2
input:
4
0 8 1 1
8 0 1 4
8 0 8 32
1 32 32 0
correct answer: 128
output: 64
#TC 3
input:
4
2 32 16 8
4 0 4 4
0 1 8 4
32 32 0 32
correct answer: 64
output: 128
코드
package boj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_12100_2048_Easy {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int max_cnt = 0;
static int N;
public static void main(String[] args) throws IOException {
N = Integer.parseInt(br.readLine());
int[][] board = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
game(board, 0, 0);
System.out.println(max_cnt);
}
static int[] dx = { 0, 0, -1, 1 };
static int[] dy = { -1, 1, 0, 0 };
public static void game(int[][] board, int cnt, int idx) {
int[][] t_board = board.clone();
for (int i = 0; i < N; i++) {
t_board[i] = board[i].clone();
}
if (cnt == 5) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
max_cnt = Math.max(max_cnt, board[i][j]);
}
}
return;
}
// 먼저 이동한 애들을 확인해야하는데..
for (int d = 0; d < 4; d++) {
boolean[][] sumChecker = new boolean[N][N];
int nx = dx[d];
int ny = dy[d];
switch (d) {
case 0:
// 왼쪽
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int t_i = i;
int t_j = j;
// 이동할 때 원래 자리에 0 을 집어넣고 이동, 벽이 아닌 다른 숫자가 나왔을 때
// 그 숫자가 같은 숫자면 합치고 현재 위치는 0
if (board[i][j] == 0) // 0이면 굳이 확인할 필요 없다.
continue;
while (0 <= i + nx && i + nx < N && 0 <= j + ny && j + ny < N) {
if (board[i + nx][j + ny] == 0) {
board[i + nx][j + ny] = board[i][j]; // 이동하려는 위치에 현재 값을 넣음
board[i][j] = 0;
}
else if (board[i + nx][j + ny] == board[i][j] && !sumChecker[i + nx][j + ny]) {
// 합쳐야하긴하는데 한번 합쳐진애는 합치면 안돼
// 한번 합쳤는지 아닌지를 어떻게 알까
// checker에 좌표를 저장해두자
board[i + nx][j + ny] += board[i][j];// 원래 있던 애 합치고
board[i][j] = 0; // 0으로 만듦
sumChecker[i + nx][j + ny] = true;
// 여기까지 왔으면 사실 더 이상 이동할 수 없음
break;
} else {
break; // 아무곳도 이동 못할 때 탈출
}
i += nx; // 좌표 이동
j += ny; // 좌표 이동
}
i = t_i;
j = t_j;
}
}
break;
case 1:
// 오른쪽 부터 확인해야 한다.
for (int i = 0; i < N; i++) {
for (int j = N - 1; j >= 0; j--) {
int t_i = i;
int t_j = j;
// 이동할 때 원래 자리에 0 을 집어넣고 이동, 벽이 아닌 다른 숫자가 나왔을 때
// 그 숫자가 같은 숫자면 합치고 현재 위치는 0
if (board[i][j] == 0) // 0이면 굳이 확인할 필요 없다.
continue;
while (0 <= i + nx && i + nx < N && 0 <= j + ny && j + ny < N) {
if (board[i + nx][j + ny] == 0) {
board[i + nx][j + ny] = board[i][j]; // 이동하려는 위치에 현재 값을 넣음
board[i][j] = 0;
}
else if (board[i + nx][j + ny] == board[i][j] && !sumChecker[i + nx][j + ny]) {
// 합쳐야하긴하는데 한번 합쳐진애는 합치면 안돼
// 한번 합쳤는지 아닌지를 어떻게 알까
// checker에 좌표를 저장해두자
board[i + nx][j + ny] += board[i][j];// 원래 있던 애 합치고
board[i][j] = 0; // 0으로 만듦
sumChecker[i + nx][j + ny] = true;
// 여기까지 왔으면 사실 더 이상 이동할 수 없음
break;
} else {
break; // 아무곳도 이동 못할 때 탈출
}
i += nx; // 좌표 이동
j += ny; // 좌표 이동
}
i = t_i;
j = t_j;
}
}
break;
case 2:
// 위쪽
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int t_i = i;
int t_j = j;
// 이동할 때 원래 자리에 0 을 집어넣고 이동, 벽이 아닌 다른 숫자가 나왔을 때
// 그 숫자가 같은 숫자면 합치고 현재 위치는 0
if (board[i][j] == 0) // 0이면 굳이 확인할 필요 없다.
continue;
while (0 <= i + nx && i + nx < N && 0 <= j + ny && j + ny < N) {
if (board[i + nx][j + ny] == 0) {
board[i + nx][j + ny] = board[i][j]; // 이동하려는 위치에 현재 값을 넣음
board[i][j] = 0;
}
else if (board[i + nx][j + ny] == board[i][j] && !sumChecker[i + nx][j + ny]) {
// 합쳐야하긴하는데 한번 합쳐진애는 합치면 안돼
// 한번 합쳤는지 아닌지를 어떻게 알까
// checker에 좌표를 저장해두자
board[i + nx][j + ny] += board[i][j];// 원래 있던 애 합치고
board[i][j] = 0; // 0으로 만듦
sumChecker[i + nx][j + ny] = true;
// 여기까지 왔으면 사실 더 이상 이동할 수 없음
break;
} else {
break; // 아무곳도 이동 못할 때 탈출
}
i += nx; // 좌표 이동
j += ny; // 좌표 이동
}
i = t_i;
j = t_j;
}
}
break;
case 3:
// 아래쪽 // x가 커진다. // 큰 수부터 이동하는걸 확인해야해
for (int i = N - 1; i >= 0; i--) {
for (int j = 0; j < N; j++) {
int t_i = i;
int t_j = j;
// 이동할 때 원래 자리에 0 을 집어넣고 이동, 벽이 아닌 다른 숫자가 나왔을 때
// 그 숫자가 같은 숫자면 합치고 현재 위치는 0
if (board[i][j] == 0) // 0이면 굳이 확인할 필요 없다.
continue;
while (0 <= i + nx && i + nx < N && 0 <= j + ny && j + ny < N) {
if (board[i + nx][j + ny] == 0) {
board[i + nx][j + ny] = board[i][j]; // 이동하려는 위치에 현재 값을 넣음
board[i][j] = 0;
}
else if (board[i + nx][j + ny] == board[i][j] && !sumChecker[i + nx][j + ny]) {
// 합쳐야하긴하는데 한번 합쳐진애는 합치면 안돼
// 한번 합쳤는지 아닌지를 어떻게 알까
// checker에 좌표를 저장해두자
board[i + nx][j + ny] += board[i][j];// 원래 있던 애 합치고
board[i][j] = 0; // 0으로 만듦
sumChecker[i + nx][j + ny] = true;
// 여기까지 왔으면 사실 더 이상 이동할 수 없음
break;
} else {
break; // 아무곳도 이동 못할 때 탈출
}
i += nx; // 좌표 이동
j += ny; // 좌표 이동
}
i = t_i;
j = t_j;
}
}
break;
}
game(board, cnt + 1, idx + 1);
for (int i = 0; i < N; i++) {
board[i] = t_board[i].clone();
}
}
}
}
결과
메모리 시간 언어
28892KB | 452ms | Java |