Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions 01_PuyoPuyo/hyoz/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from collections import deque
field = []
directions = [[-1, 0], [0, -1], [1, 0], [0, 1]] # 상하좌우


def bfs(color, x, y, visited):
'''
동일 색상에 대해 BFS를 수행하는 함수 (반환값: 인접한 동일한 색상의 개수)

<Parameters>
- color: 현재 탐색해야 할 색상
- x, y: 시작 좌표
- visited: 방문 여부 판단 배열
'''
queue = deque([(x, y)]) # BFS 탐색용 큐
coords = [(x, y)] # 4개 이상일 때 제거를 위해 반환할 좌표 배열
cnt = 1
while queue:
cx, cy = queue.popleft()

visited[cx][cy] = True # 방문 처리
for dx, dy in directions:
nx, ny = cx+dx, cy+dy
if (nx >= 0 and nx < 6) and (ny >= 0 and ny < 12): # 배열 범위 내
if field[nx][ny] == color and not visited[nx][ny]:
queue.append((nx, ny))
coords.append((nx, ny))
cnt += 1
visited[nx][ny]=True
return cnt, coords


# 필드 입력
for _ in range(12):
field.append(input())

# 필드 90도 시계방향으로 회전
field = [list(e) for e in zip(*field[::-1])]

answer = 0
while True:
visited = [[False]*12 for _ in range(6)] # 방문 여부 판단 배열

remove_coords = [] # 1연쇄 시 제거해야 할 좌표들

for x in range(6):
for y in range(12):
if field[x][y] != '.':
if not visited[x][y]:
cnt, coords = bfs(field[x][y], x, y, visited)
if cnt >= 4:
remove_coords.extend(coords)

if len(remove_coords) > 0:
# Clear
Xs = []
for x in range(6):
col = ''
for y in range(12):
if (x, y) not in remove_coords and field[x][y] != '.':
col += field[x][y]
field[x] = list(col.ljust(12, '.'))

answer += 1
else:
print(answer)
break
142 changes: 142 additions & 0 deletions 01_PuyoPuyo/hyoz/description.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "0996ea12-48c5-4477-9021-61bc706bca9f",
"metadata": {},
"source": [
"# Description"
]
},
{
"cell_type": "markdown",
"id": "46642a35-6e36-49bb-ab6b-bcab05a2e8e4",
"metadata": {},
"source": [
"### 문제 개요\n",
"* 문제: [Puyo Puyo](https://www.acmicpc.net/problem/11559)\n",
"* 문제 요약\n",
" * 동일한 색상이 4개 이상 인접한 블럭을 제거한다. 제거된 블럭 위에 있던 블럭은 아래로 떨어지며, 떨어진 후 4개 이상 인접한 블럭이 있을 경우 또 다시 제거하는 연쇄 작용이 발생한다. 이러한 연쇄 작용이 몇 번 일어나는지 찾는 문제이다.\n",
" * 입력: 5가지 색상(R, G, B, P, Y)의 블럭과 빈칸(.)으로 구성된 2차원 배열\n",
" * 출력: 연쇄 작용이 일어난 횟수 (정수값)\n",
"* 문제 유형: 그래프 탐색\n"
]
},
{
"cell_type": "markdown",
"id": "efa2d101-5e24-4ae2-98f2-973ca0aa9fed",
"metadata": {},
"source": [
"# History of Code"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6293dd8-87a6-4f72-aa3e-98580143c5e0",
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"시간 복잡도: O(n^3)\n",
"\n",
"구현 순서\n",
"1. 입력 받은 2차원 좌표를 돌면서 방문하지 않은 색상 블럭에 대해 BFS 함수를 수행한다. -> O(n^2)\n",
"1-1. 이 때, 입력받은 2차원 배열은 시계 방향으로 90도 회전하여 아래로 내려오는 한 라인을 하나의 배열에 할당한다.\n",
"2. BFS를 통해 인접한 동일 색상의 블럭 개수를 반환하고, 이 개수가 4개 이상인 경우 제거 블록에 추가한다.\n",
"3. 제거 블록이 있는 경우, 해당 좌표를 제거한 후 남은 부분을 빈칸으로 채워주고 1번으로 다시 돌아간다.\n",
"4. 제거 블럭이 없는 경우 현재 연쇄 횟수를 출력하고 반환한다.\n",
"\"\"\"\n",
"\n",
"from collections import deque\n",
"field = []\n",
"directions = [[-1, 0], [0, -1], [1, 0], [0, 1]] # 상하좌우\n",
"\n",
"\n",
"def bfs(color, x, y, visited):\n",
" ''' \n",
" 동일 색상에 대해 BFS를 수행하는 함수 (반환값: 인접한 동일한 색상의 개수)\n",
" \n",
" <Parameters>\n",
" - color: 현재 탐색해야 할 색상\n",
" - x, y: 시작 좌표\n",
" - visited: 방문 여부 판단 배열\n",
" '''\n",
" queue = deque([(x, y)]) # BFS 탐색용 큐\n",
" coords = [(x, y)] # 4개 이상일 때 제거를 위해 반환할 좌표 배열\n",
" cnt = 1\n",
" while queue:\n",
" cx, cy = queue.popleft()\n",
" \n",
" visited[cx][cy] = True # 방문 처리\n",
" for dx, dy in directions:\n",
" nx, ny = cx+dx, cy+dy\n",
" if (nx >= 0 and nx < 6) and (ny >= 0 and ny < 12): # 배열 범위 내\n",
" if field[nx][ny] == color and not visited[nx][ny]:\n",
" queue.append((nx, ny))\n",
" coords.append((nx, ny))\n",
" cnt += 1\n",
" visited[nx][ny]=True\n",
" return cnt, coords\n",
"\n",
"\n",
"# 필드 입력\n",
"for _ in range(12):\n",
" field.append(input())\n",
"\n",
"# 필드 90도 시계방향으로 회전\n",
"field = [list(e) for e in zip(*field[::-1])]\n",
"\n",
"answer = 0\n",
"while True:\n",
" visited = [[False]*12 for _ in range(6)] # 방문 여부 판단 배열\n",
"\n",
" remove_coords = [] # 1연쇄 시 제거해야 할 좌표들\n",
"\n",
" for x in range(6):\n",
" for y in range(12):\n",
" if field[x][y] != '.':\n",
" if not visited[x][y]:\n",
" cnt, coords = bfs(field[x][y], x, y, visited)\n",
" if cnt >= 4: \n",
" remove_coords.extend(coords)\n",
"\n",
" if len(remove_coords) > 0:\n",
" # Clear\n",
" Xs = []\n",
" for x in range(6):\n",
" col = ''\n",
" for y in range(12):\n",
" if (x, y) not in remove_coords and field[x][y] != '.':\n",
" col += field[x][y]\n",
" field[x] = list(col.ljust(12, '.'))\n",
"\n",
" answer += 1\n",
" else:\n",
" print(answer)\n",
" break"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}