BOJ 2933 미네랄 python
2022년 11월 22일
#algorithm#boj#python
문제
풀이
- 막대기를 던진 줄을 차례대로 for문을 돌면서, 미네랄이 있으면 지우고, 없으면 continue
- 미네랄 주위 4칸 dfs, 바닥을 만나면 ans.append(1)을 해주고 ans != 0이면 continue
- ans == 0이면 각 열을 돌면서 떨어질 수 있는 값을 moved에 저장, 아래부터 미네랄을 옮김
알고리즘 자체는 간단한 dfs인데, 구현이 까다로운 문제였다. 미리 마지막 줄을 미네랄로 채워주면, 따로 예외처리를 안해도 된다.
풀이 코드
import sys
sys.setrecursionlimit(10**6)
rl = sys.stdin.readline
r, c = map(int, rl().split())
g = [list(rl().rstrip()) for _ in range(r)]
g.append(["x"]*c)
n = int(rl())
qr = [r-i for i in list(map(int, rl().split()))]
dr = [(1,0),(-1,0),(0,1),(0,-1)]
def dfs(x, y):
if y == r: out.append(1)
if dp[y][x] == 0:
dp[y][x] = 1
for dx, dy in dr:
if not (0<=x+dx<c and 0<=y+dy<r+1): continue
if dp[y+dy][x+dx]: continue
if g[y+dy][x+dx] == 'x': dfs(x+dx,y+dy)
rlch = 1
for y in qr:
if rlch: x = ''.join(g[y]).find('x')
else: x = c-1-''.join(reversed(g[y])).find('x')
if x == -1 or x == c:
rlch = (rlch+1)%2
continue
g[y][x] = '.'
for dx, dy in dr:
if not (0<=x+dx<c and 0<=y+dy<r+1): continue
if g[y+dy][x+dx] == '.': continue
out = []
dp = [[0 for _ in range(c)] for _ in range(r+1)]
dfs(x+dx,y+dy)
if not out:
moved = r
for chx in range(c):
chy, nowy = 0, -200
while chy <= r:
if dp[chy][chx]: nowy = chy
elif g[chy][chx] == 'x': moved = min(moved, chy-nowy-1)
chy += 1
for i in range(r, -1, -1):
for j in range(c):
if dp[i][j] == 0: continue
g[i][j] = '.'
g[i+moved][j] = 'x'
break
rlch = (rlch+1)%2
for i, gg in enumerate(g):
if i != r: print(''.join(gg))관련 글
백준 2927 남극탐험 Python
https://www.acmicpc.net/problem/2927 트리에서 노드 연결, 단일 업데이트, 구간합 쿼리를 수행하는 문제이다. 연결 여부는 union-find로 관리하고, 먼저 모든 연결 쿼리를 수행하여 HLD를 해준다. 이후, 순서대로 쿼리를 처리하면 된다. HLD 과...
BOJ 25910 게이트웨이 정하기 python
문제 게이트웨이 정하기 풀이 비트 연산의 특징을 알아야 풀 수 있는 문제였다. 1. 임의의 노드에서 시작한 결과를 dp에 저장한다. 2. 각 비트를 0인 그룹과, 1인 그룹으로 나눈다.(temp에 1일 경우만 저장) 3. 모든 노드에 대해 헤더와 XOR연산으로 비용을 구한다. 4....
programmers 행렬과 연산 python
문제 행렬과 연산 풀이 표를 적당히 쪼개서 deque로 풀면 된다. 맨 왼쪽 열과 맨 오른쪽 열을 따로 저장해서 deque 2개를 만들고, 각 행의 인덱스를 저장한 deque를 만든다. 연산 시, q, leftq, rightq에 저장된 마지막 인덱스를 맨 앞으로 옮겨준다. 연산 시...