12100 2048 (Easy)
https://www.acmicpc.net/problem/12100문제설명
주어진 n x n 격자에 숫자가 배치되어 있고, 사용자는 숫자를 이동시키는 방향을 선택하여
합쳐질 수 있는 숫자를 더해나가며 최대 숫자를 만들려고 한다.
숫자는 상하좌우로 이동할 수 있으며, 같은 숫자가 만나면 합쳐지고 새로운 숫자가 생성된다.
목표는 여러 번의 이동 후 격자에서 가장 큰 숫자를 찾는다.
접근방식
DFS를 사용해 각 조합에 대해 격자를 한 번씩 순회하므로 O(n^2)의 시간복잡도를 가진다.
문제 조건 분석 과정
- DFS를 통한 방향 조합 생성:
- 4가지 방향(상, 우, 하, 좌) 중에서 5번의 이동 방향을 선택하는 모든 조합을 생성하기 위해
- DFS(Depth First Search)를 사용한다. 방향은 0, 1, 2, 3으로 각각 상, 우, 하, 좌를 나타낸다.
- 이동 및 합치기:
- 선택된 방향으로 격자를 순회하며 이동 및 합치기를 진행한다.
- move() 메소드를 사용하여 숫자를 이동시키고, 같은 숫자가 만났을 때 합치는 로직을 구현한다.
- 최대 숫자 찾기:
- 모든 이동이 완료된 후, 격자에서 가장 큰 숫자를 찾아 max에 저장한다.
- 모든 조합을 확인한 후 최댓값을 출력한다.
전체코드
import java.util.*;
import java.io.*;
public class Main {
private static int n;
private static int[][] map;
private static int[][] temp;
private static int[] direct;
private static boolean[][] visit;
private static int max = 0;
private static int[] dx = {-1, 0, 1, 0};
private static int[] dy = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(reader.readLine());
map = new int[n+1][n+1];
direct = new int[5];
StringTokenizer st;
for (int i = 1; i <= n; i++) {
st = new StringTokenizer(reader.readLine());
for (int j = 1; j <= n; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
dfs(5, 0);
System.out.println(max);
}
private static void dfs(int end, int index) {
if (index == end) {
confirm();
} else {
for (int i = 0; i < 4; i++) {
direct[index] = i;
dfs(end, index + 1);
}
}
}
private static void confirm() {
temp = new int[n+1][n+1];
for (int i = 1; i <= n; i++) {
temp[i] = map[i].clone();
}
for (int d = 0; d < direct.length; d++) {
visit = new boolean[n+1][n+1];
if (direct[d] == 0) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
move(i, j, direct[d]);
}
}
} else if (direct[d] == 2) {
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= n; j++) {
move(i, j, direct[d]);
}
}
} else if (direct[d] == 1) {
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= n; j++) {
move(j, i, direct[d]);
}
}
} else {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
move(j, i, direct[d]);
}
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (temp[i][j] > max) {
max = temp[i][j];
}
}
}
}
private static void move(int x, int y, int dir) {
if (temp[x][y] == 0) {
return;
}
while (true) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if (nx < 1 || ny < 1 || nx > n || ny > n) {
return;
}
if (visit[nx][ny]) {
return;
}
if (temp[nx][ny] == temp[x][y]) {
visit[nx][ny] = true;
temp[nx][ny] *= 2;
temp[x][y] = 0;
return;
} else if (temp[nx][ny] != 0) {
return;
}
temp[nx][ny] = temp[x][y];
temp[x][y] = 0;
x = nx;
y = ny;
}
}
}
'자료구조 > 문제풀이' 카테고리의 다른 글
[백준 JAVA] 8911 거북이 (1) | 2024.09.21 |
---|---|
[백준 JAVA] 5212 지구 온난화 (1) | 2024.09.21 |
[백준 JAVA] 15685 드래곤 커브 (0) | 2024.09.21 |
알고리즘 스터디 1주차 문제정리 (1) | 2024.09.15 |
[백준 JAVA] 16987 계란으로 계란치기 (1) | 2024.09.13 |