728x90

문제

 

12100번: 2048 (Easy)

첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2

www.acmicpc.net

 

접근 방식

정말 있는 그대로 구현하기만 하면 되서 티어에 비해 쉬운 문제다.

 

많이들 실수하는 부분이 전역 변수 관리나 객체의 얕은 복사인데

이 부분만 조심하면 풀이에 어려움은 없다.

 

움직이고자 하는 방향의 끝 인덱스에서부터 거꾸로 탐색해주면서

수가 같다면 합쳐주면 되는데 0인 경우를 조심해야 한다.

 

현재 바라보고 있는 곳이 0이라면 어떤 값이든 들어올 수 있으니

처음 마주치는 값을 옮겨주고 그 후에 같은 값이 있는지 또 확인해준다.

 

반대로 현재 바라보고 있는 곳이 0이 아니라면 같은 숫자만

합칠 수 있으니 같은 값이 있는지 한 번만 확인해주면 된다.

 

만약 수가 같지 않다면 멈춘다.

 

풀이

public class Main {

	static int n, max = 0;
	static int[] move = new int[5];
	static int[][] board, newBoard;

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

		n = Integer.parseInt(br.readLine());
		board = new int[n][n];
		newBoard = 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());
				newBoard[i][j] = board[i][j];
			}
		}

		solve(0);

		System.out.println(max);
	}

	static void solve(int cnt) {
		if (cnt == 5) {
			for (int i = 0; i < 5; i++) {
				move(move[i]);
			}
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					max = Math.max(max, board[i][j]);
				}
			}
			back();
			return;
		}

		for (int dir = 0; dir < 4; dir++) {
			move[cnt] = dir;
			solve(cnt + 1);
		}
	}

	static void move(int dir) {
		switch(dir) {
			case 0: {
				right();
				break;
			}
			case 1: {
				left();
				break;
			}
			case 2: {
				up();
				break;
			}
			default: {
				down();
				break;
			}
		}
	}

	static void right() {
		for (int i = 0; i < n; i++) { 
			for (int j = n - 1; j >= 0; j--) { 
				for (int k = j - 1; k >= 0; k--) { 
					if (board[i][k] != 0) {
						if (board[i][j] == 0) {
							board[i][j] = board[i][k];
							board[i][k] = 0;
							continue;
						}

						if (board[i][j] == board[i][k]) {
							board[i][j] *= 2;
							board[i][k] = 0;
						}

						break;
					}
				}
			}
		}
	}

	static void left() {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = j + 1; k < n; k++) {
					if (board[i][k] != 0) {
						if (board[i][j] == 0) {
							board[i][j] = board[i][k];
							board[i][k] = 0;
							continue;
						}

						if (board[i][j] == board[i][k]) {
							board[i][j] *= 2;
							board[i][k] = 0;
						}
						break;
					}
				}
			}
		}
	}

	static void up() {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = j + 1; k < n; k++) {
					if (board[k][i] != 0) {
						if (board[j][i] == 0) {
							board[j][i] = board[k][i];
							board[k][i] = 0;
							continue;
						}

						if (board[j][i] == board[k][i]) {
							board[j][i] *= 2;
							board[k][i] = 0;
						}
						break;
					}
				}
			}
		}
	}

	static void down() {
		for (int i = 0; i < n; i++) {
			for (int j = n - 1; j >= 0; j--) {
				for (int k = j - 1; k >= 0; k--) {
					if (board[k][i] != 0) {
						if (board[j][i] == 0) {
							board[j][i] = board[k][i];
							board[k][i] = 0;
							continue;
						}

						if (board[j][i] == board[k][i]) {
							board[j][i] *= 2;
							board[k][i] = 0;
						}
						break;
					}
				}
			}
		}
	}

	static void back() {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				board[i][j] = newBoard[i][j];
			}
		}
	}
}

 

'Java > Algorithms' 카테고리의 다른 글

[백준] 15686번 : 치킨 배달  (0) 2024.04.01
[백준] 3055번 : 탈출  (0) 2024.03.31
[백준] 14502번 : 연구소  (1) 2024.03.29
[백준] 14889번 : 스타트와 링크  (0) 2024.03.29
[백준] 14888번 : 연산자 끼워넣기  (0) 2024.03.28

+ Recent posts