From 818df10475bbaf331b081e7ca83b6e5a45bcbafe Mon Sep 17 00:00:00 2001 From: Woo-Yeol Date: Thu, 12 Oct 2023 00:20:33 +0900 Subject: [PATCH 1/2] Create 2048 (Easy) wooyeol.py --- BOJ/2048 (Easy)/wooyeol.py | 129 ++++++++++++++++++++++++++++++++++++ BOJ/2048 (Easy)/wooyeol2.py | 90 +++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 BOJ/2048 (Easy)/wooyeol.py create mode 100644 BOJ/2048 (Easy)/wooyeol2.py diff --git a/BOJ/2048 (Easy)/wooyeol.py b/BOJ/2048 (Easy)/wooyeol.py new file mode 100644 index 00000000..d332182a --- /dev/null +++ b/BOJ/2048 (Easy)/wooyeol.py @@ -0,0 +1,129 @@ +""" + 2048 (Easy) + https://www.acmicpc.net/problem/12100 + + 풀이시간 + 14:11 ~ 15:02(오답) + 4시간 정도 재 풀이 및 레퍼런스 참고 (실패) + + - 실패한 풀이 - +""" +import sys +import copy + +sys.setrecursionlimit(10 ** 6) + +input = sys.stdin.readline + +def oob(x,y,dx,dy): + return 0 <= x + dx < N and 0 <= y + dy < N + # return (0 > x + dx) or (x + dx > N) or (y + dy < 0) or (y + dy > N) + +def swipe(direction, t_board): + # col,row + l_row, l_col = len(t_board), len(t_board[0]) + + # 상하좌우 + directions = ((-1,0), (1,0), (0,-1), (0,1)) + directions_increase = ((range(1,l_row), range(l_row-2,-1,-1), range(1, l_col),range(l_col-2,-1,-1))) + + # 상 하 움직일 경우 + if direction in (0, 1): + for c_idx in range(l_col): + is_combined = [False] * l_row + for r_idx in directions_increase[direction]: + x, y = r_idx, c_idx + + # 빈칸이면 이동하지 않는다. + if t_board[x][y]: + # 주어진 방향으로 한 칸 이동 + dx, dy = directions[direction] + nx, ny = x + dx, y + dy + + # nx,ny가 보드를 벗어난 다면 Break + if not oob(x, y, dx, dy): + break + + # print(nx, ny, x, y) + + # 빈칸일 경우 + if t_board[nx][ny] == 0: + t_board[nx][ny] = t_board[x][y] + t_board[x][y] = 0 + + # 같은 값이 있는 경우 + if t_board[nx][ny] == t_board[x][y] and not is_combined[nx]: + t_board[nx][ny] *= 2 + t_board[x][y] = 0 + is_combined[nx] = True + + print("\nAfter Swipe", direction) + for row in t_board: + print(*row) + + # 좌 우 움직일 경우 + elif direction in (2, 3): + for r_idx in range(l_row): + is_combined = [False] * l_col + for c_idx in directions_increase[direction]: + x, y = r_idx, c_idx + + # 빈칸이면 이동하지 않는다. + if board[x][y]: + # 주어진 방향으로 한 칸 이동 + dx, dy = directions[direction] + nx, ny = x + dx, y + dy + + # nx,ny가 보드를 벗어난다면 Break + if not oob(x, y, dx, dy): + break + + # 빈칸일 경우 + if t_board[nx][ny] == 0: + t_board[nx][ny] = t_board[x][y] + t_board[x][y] = 0 + + # 같은 값이 있는 경우 + if t_board[nx][ny] == t_board[x][y] and not is_combined[ny]: + t_board[nx][ny] *= 2 + t_board[x][y] = 0 + is_combined[ny] = True + + +max_value = -1 + +def dfs(repeat, board): + # 종료 조건 + if repeat == 1: + global max_value + + # flag = False + for row in board: + temp_max_value = max(row) + if temp_max_value > max_value: + # flag = True + max_value = temp_max_value + # if flag: + # print("\n",max_value) + # for row in board: + # print(*row) + + return + + temp = copy.deepcopy(board) + # 상 하 좌 우 + for direction in range(4): + swipe(direction, temp) + dfs(repeat+1, temp) + temp = copy.deepcopy(board) + + + +N = int(input()) + +board = [] +for _ in range(N): + board.append(list(map(int, input().split()))) + +dfs(0, board) +print(max_value) \ No newline at end of file diff --git a/BOJ/2048 (Easy)/wooyeol2.py b/BOJ/2048 (Easy)/wooyeol2.py new file mode 100644 index 00000000..a2daf965 --- /dev/null +++ b/BOJ/2048 (Easy)/wooyeol2.py @@ -0,0 +1,90 @@ +""" + 2048 (Easy) + https://www.acmicpc.net/problem/12100 + + 풀이시간 + 23:23 ~ 24:14(49분) + + 문제 조건 + 1 <= N <=20 + + 시간 복잡도 : O(N^3 * 4 * 4 ^ 5) + O(32,768,000) + + 접근법 + 무슨 알고리즘으로 풀이 할 수 있을까? -> 시뮬레이션(백 트래킹) +""" +import sys +import copy +from collections import deque + +input = sys.stdin.readline + +queue = deque() + +def swipe(x, y): + if board[x][y]: + queue.append(board[x][y]) + board[x][y] = 0 + + +def merge(x, y, direction): + dx, dy = direction + while queue: + value = queue.popleft() + # 빈칸이라면 현재 값 채우기 + if not board[x][y]: + board[x][y] = value + # 해당 칸의 값과 현재 값이 같다면 두배 + elif board[x][y] == value: + board[x][y] *= 2 + x, y = x+dx, y+dy + # 해당 칸의 값과 현재 값이 다르다면 다음 칸에 배치 + elif board[x][y] != value: + x, y = x+dx, y+dy + board[x][y] = value + + +def turn(direct): + # 상하우좌 + directions_from = (0, N-1) + directions = ((1, 0), (-1, 0), (0, 1), (0, -1)) + directions_increase = (range(1, N), range(N-2, -1, -1)) + + if direct in (0, 1): + for y in range(N): + for x in directions_increase[direct % 2]: + swipe(x, y) + merge(directions_from[direct % 2], y, directions[direct]) + elif direct in (2, 3): + for x in range(N): + for y in directions_increase[direct % 2]: + swipe(x, y) + merge(x, directions_from[direct % 2], directions[direct]) + + +def dfs(idx): + global board, answer + + # 종료 조건 + if idx == 5: + for i in range(N): + temp_max = max(board[i]) + if temp_max > answer: + answer = temp_max + return + + board_copy = copy.deepcopy(board) + + for direct in range(4): + turn(direct) + dfs(idx + 1) + board = copy.deepcopy(board_copy) + + +N = int(input()) +board = [list(map(int, input().split())) for _ in range(N)] +answer = 0 + +dfs(0) +print(answer) \ No newline at end of file From 6bfef000b116b770b0017ee91c6f07a227dbf1ea Mon Sep 17 00:00:00 2001 From: Woo-Yeol Date: Thu, 12 Oct 2023 00:30:58 +0900 Subject: [PATCH 2/2] Update 2048 (Easy) wooyeol2.py --- BOJ/2048 (Easy)/wooyeol2.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BOJ/2048 (Easy)/wooyeol2.py b/BOJ/2048 (Easy)/wooyeol2.py index a2daf965..279be2bb 100644 --- a/BOJ/2048 (Easy)/wooyeol2.py +++ b/BOJ/2048 (Easy)/wooyeol2.py @@ -4,6 +4,7 @@ 풀이시간 23:23 ~ 24:14(49분) + 풀이 참조 : https://jeongchul.tistory.com/667 문제 조건 1 <= N <=20 @@ -13,6 +14,12 @@ 접근법 무슨 알고리즘으로 풀이 할 수 있을까? -> 시뮬레이션(백 트래킹) + + - 시뮬레이션을 위한 함수들을 선언해주었습니다. + 1. swipe : 한 행 혹은 칼럼의 값 중 0이 아닌 값들을 queue에 넣는 역할을 수행합니다 -> 한 쪽으로 쓸기 + 2. merge : queue에 들어있는 값들을 모두 검사하며 동일한 값이 두 번 나오면 합치고 다른 값이 나온다면 다른 칸에 값 채우기 + 3. turn : 한 번의 턴을 의미하며 상하우좌를 기준으로 입력받은 방향으로 swipe 후 merge를 진행합니다. + 4. dfs : 백 트래킹 기법을 통해 5번의 연산 후 최대 값을 찾습니다. """ import sys import copy