https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRF8s6ezEDFAUo&
dx=[-1,0,1,0]
dy=[0,1,0,-1]
def simulation(sx,sy,sd):
global answer
started=False
x,y,d=sx,sy,sd
cnt=0
while True:
if started and x==sx and y==sy:
break
if board[x][y]==-1:
break
if not started:
started=True
if 1<=board[x][y]<=4:
if board[x][y]==1:
if d==3:
d=0
elif d==2:
d=1
elif board[x][y]==2:
if d==0:
d=1
elif d==3:
d=2
elif board[x][y]==3:
if d==1:
d=2
elif d==0:
d=3
elif board[x][y]==4:
if d==2:
d=3
elif d==1:
d=0
cnt+=1
nx=x+dx[d]
ny=y+dy[d]
if (nx<0 or ny<0 or nx>=n or ny>=n) or (board[nx][ny]==5) or (board[nx][ny]==1 and (d==1 or d==0)) or (board[nx][ny]==2 and (d==1 or d==2)) or (board[nx][ny]==3 and (d==2 or d==3)) or (board[nx][ny]==4 and (d==3 or d==0)):
cnt+=1
d=(d+2)%4
nx,ny=x,y
x,y=nx,ny
if 6<=board[x][y]<=10:
for k in range(2):
if (x,y)!=hole[board[x][y]][k]:
x,y=hole[board[x][y]][k]
break
# print(x,y)
answer=max(answer,cnt)
for tc in range(1,int(input())+1):
n=int(input())
hole=dict()
answer=0
board=[list(map(int,input().split())) for _ in range(n)]
for i in range(n):
for j in range(n):
if 6<=board[i][j]<=10:
if board[i][j] not in hole:
hole[board[i][j]]=[]
hole[board[i][j]].append((i,j))
answer=0
for x in range(n):
for y in range(n):
if board[x][y]==0:
for d in range(4):
simulation(x,y,d)
print("#"+str(tc)+" "+str(answer))
핀볼이 움직이는 상황을 시뮬레이션 하는 문제이다. 각 보드에 따라 벽과 이동하는 홀이 있고 끝나는 블랙홀도 존재한다. 이에 맞추어 시뮬레이션이 작동되게 하면 된다.
먼저 모든 빈칸에서 4가지 방향 전부로 움직임을 계산해야 하므로 for문을 중첩하여 이를 simulation 함수에 넣어준다. 이렇게 하기 전에 웜홀의 위치는 이동할 때 필요했기에 미리 분리해서 dict()에 넣어주었다.
먼저 공이 시작 지점부터 시작되면 while문으로 무한실행하면서 측정하돼 종료조건을 달아준다. 시작 직후를 제외하고 시작지점으로 돌아오면 break 시켜주고 블랙홀에 들어갔을 경우도 break시켜준다. 이제 현재 위치가 벽인 즉, 삼각형 모양의 벽이라 방향이 바뀌는 것을 고려하여 다음방향을 바꿔준다. 이 때는 벽에 닿았을 경우이기 때문에 점수를 +1해준다. 그리고나서 현재방향에 따라 방향이 정반대가 되는 상황도 전부따져준다. 이 때도 점수는 마찬가지로 +1해주면 된다.
이제 현재 위치가 웜홀일 때, 현재위치를 갱신시켜주어야 한다. 간단히 dict에서 찾아서 다른 하나의 좌표로 이동시켜주면 간단하다.
이렇게 Python로 SWEA의 "핀볼 게임" 문제를 해결해보았습니다. 코드와 개념 설명을 참고하여 문제를 해결하는 데 도움이 되셨길 바랍니다! 😊