반응형
문제
https://www.acmicpc.net/problem/12100
[12100번: 2048 (Easy)
첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2
www.acmicpc.net](https://www.acmicpc.net/problem/12100)
풀이
이 문제는 dfs를 사용하여 접근하였습니다.
- 경우의 수는 상, 하, 좌, 우 4가지 경우의 수가 있습니다.
- 따라서
for
문으로 4가지 방향에 대해서 블록을 이동시켜줍니다. - 기존
board
배열에서copy
라는 새로운 배열을 만들어줘서 한줄씩 이동시켜줍니다. - 값이 0이 아닌 경우에 값을 옮깁니다.
- 이 때 이전에 옮긴 값과 현재 값을 합칠 지 확인해야합니다.
- 만약 이전에 옮긴 값이 없다면 합치지 않고 그대로 옮겨줍니다.
- 이전에 옮긴 값과 현재 값이 같다면 두 값을 합쳐주고
visited
라는 불린값을true
로 체크해줍니다. - 값이 다르다면 그대로 옮겨주고
visited
값을false
로 합니다.
- 이렇게 5번 반복한다면 블록안에서 최대값이 있는지 확인하고 있다면
max
값을 갱신합니다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n;
static int[][] board;
static int max = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
board = new int[n][n];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
game(0);
System.out.println(max);
}
public static void game(int cnt) {
// 5번 움직인 경우 배열에서 가장 큰값이 있다면 max를 갱신합니다.
if (cnt == 5) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
max = Math.max(max, board[i][j]);
}
}
return;
}
for (int d = 0; d < 4; d++) {
int[][] copy = new int[n][n];
switch (d) {
// 위로 움직임
case 0:
for (int i = 0; i < n; i++) {
int idx = 0;
boolean visited = false;
for (int j = 0; j < n; j++) {
// 현재 위치의 값이 0이 아닌경우 위치를 옮겨야함
if (board[i][j] != 0) {
if (idx == 0) {
// 처음으로 움직이는 값인 경우
copy[i][idx] = board[i][j];
idx++;
} else {
if (!visited && copy[i][idx - 1] == board[i][j]) {
// 그 전 값이 합쳐지지 않았고 두 값이 같은 경우 합쳐야합니다.
copy[i][idx - 1] *= 2;
visited = true;
} else {
copy[i][idx] = board[i][j];
visited = false;
idx++;
}
}
}
}
}
break;
// 아래로 움직임
case 1:
for (int i = 0; i < n; i++) {
int idx = n - 1;
boolean visited = false;
for (int j = n - 1; j >= 0; j--) {
// 현재 위치의 값이 0이 아닌경우 위치를 옮겨야함
if (board[i][j] != 0) {
if (idx == n - 1) {
// 처음으로 움직이는 값인 경우
copy[i][idx] = board[i][j];
idx--;
} else {
if (!visited && copy[i][idx + 1] == board[i][j]) {
// 그 전 값이 합쳐지지 않았고 두 값이 같은 경우 합쳐야합니다.
copy[i][idx + 1] *= 2;
visited = true;
} else {
copy[i][idx] = board[i][j];
visited = false;
idx--;
}
}
}
}
}
break;
// 왼쪽으로 움직임
case 2:
for (int i = 0; i < n; i++) {
int idx = 0;
boolean visited = false;
for (int j = 0; j < n; j++) {
// 현재 위치의 값이 0이 아닌경우 위치를 옮겨야함
if (board[j][i] != 0) {
if (idx == 0) {
// 처음으로 움직이는 값인 경우
copy[idx][i] = board[j][i];
idx++;
} else {
if (!visited && copy[idx - 1][i] == board[j][i]) {
// 그 전 값이 합쳐지지 않았고 두 값이 같은 경우 합쳐야합니다.
copy[idx - 1][i] *= 2;
visited = true;
} else {
copy[idx][i] = board[j][i];
visited = false;
idx++;
}
}
}
}
}
break;
// 오른쪽으로 움직임
case 3:
for (int i = 0; i < n; i++) {
int idx = n - 1;
boolean visited = false;
for (int j = n - 1; j >= 0; j--) {
// 현재 위치의 값이 0이 아닌경우 위치를 옮겨야함
if (board[j][i] != 0) {
if (idx == n - 1) {
// 처음으로 움직이는 값인 경우
copy[idx][i] = board[j][i];
idx--;
} else {
if (!visited && copy[idx + 1][i] == board[j][i]) {
// 그 전 값이 합쳐지지 않았고 두 값이 같은 경우 합쳐야합니다.
copy[idx + 1][i] *= 2;
visited = true;
} else {
copy[idx][i] = board[j][i];
visited = false;
idx--;
}
}
}
}
}
}
int[][] tmp = new int[n][n];
for (int i = 0; i < n; i++) {
tmp[i] = board[i].clone();
}
board = copy;
game(cnt + 1);
board = tmp;
}
}
}
반응형
'알고리즘 풀이 > 백준' 카테고리의 다른 글
자바(Java) 백준 16948 데스 나이트 풀이 (0) | 2022.07.26 |
---|---|
자바(Java) 백준 16928 뱀과 사다리 게임 풀이 (0) | 2022.07.26 |
자바(Java) 백준 13460 구슬 탈출 2 풀이 (0) | 2022.07.26 |
자바(Java) 백준 1062 가르침 풀이 (0) | 2022.07.25 |
자바(Java) 백준 14501 퇴사 풀이 (0) | 2022.07.18 |