# 입력
N, M, H, K = map(int, input().split())
graph = [["-" for _ in range(N)] for _ in range(N)]
runners = []
for i in range(M):
x, y, d = map(int, input().split())
# +1 -> default(오른쪽, 아래)
# -1 -> 왼쪽, 위
runners.append([x-1, y-1, d, 1])
graph[x-1][y-1] = "R"
trees = []
for i in range(H):
x, y = map(int, input().split())
trees.append([x-1, y-1])
catcher = [N//2, N//2, "T"]
changeDir = []
total = 0
score = 0
while len(changeDir) <= 100:
for cd in range(1, N):
for _ in range(2):
total += cd
changeDir.append(total)
if cd == N-1:
total += cd
changeDir.append(total)
for cd in range(N-1, 0, -1):
for _ in range(2):
total += cd
changeDir.append(total)
if cd == N-1:
total += cd
changeDir.append(total)
graph[N//2][N//2] = "C"
def findByPosition(row, col):
global runners
itemTemp = []
for item in runners:
if item[0] == row and item[1] == col:
itemTemp.append(item)
return itemTemp
def graphInit():
global graph, runners
graph = [["-" for _ in range(N)] for _ in range(N)]
for itr in runners:
r, c = itr[0], itr[1]
graph[r][c] = "R"
def simulate(turn):
global runners, catcher, trees, graph, score
reverse = False
if (turn//(N*N-1))%2 == 1:
reverse = True
# 도망자
for idx, rn in enumerate(runners):
if abs(catcher[0]-rn[0]) + abs(catcher[1]-rn[1]) <= 3:
# 좌우
if rn[2] == 1:
nxtX, nxtY = -1, -1
if rn[3] == 1:
nxtX, nxtY = rn[0], rn[1]+1
elif rn[3] == -1:
nxtX, nxtY = rn[0], rn[1]-1
# 범위 확인
if 0 <= nxtX < N and 0 <= nxtY < N:
if nxtX == catcher[0] and nxtY == catcher[1]:
continue
if nxtY == N-1 or nxtY == 0:
runners[idx] = [nxtX, nxtY, rn[2], (-1)*rn[3]]
else:
runners[idx] = [nxtX, nxtY, rn[2], rn[3]]
else:
direction = rn[3]*(-1)
if direction == 1:
if rn[0] == catcher[0] and rn[1]+1 == catcher[1]:
runners[idx] = [rn[0], rn[1], rn[2], direction]
continue
runners[idx] = [rn[0], rn[1]+1, rn[2], direction]
elif direction == -1:
if rn[0] == catcher[0] and rn[1]-1 == catcher[1]:
runners[idx] = [rn[0], rn[1], rn[2], direction]
continue
runners[idx] = [rn[0], rn[1] - 1, rn[2], direction]
# 상하
elif rn[2] == 2:
nxtX, nxtY = -1, -1
if rn[3] == 1:
nxtX, nxtY = rn[0]+1, rn[1]
elif rn[3] == -1:
nxtX, nxtY = rn[0]-1, rn[1]
# 범위 확인
if 0 <= nxtX < N and 0 <= nxtY < N:
if nxtX == catcher[0] and nxtY == catcher[1]:
continue
if nxtX == 0 or nxtX == N-1:
runners[idx] = [nxtX, nxtY, rn[2], (-1) * rn[3]]
else:
runners[idx] = [nxtX, nxtY, rn[2], rn[3]]
else:
direction = rn[3] * (-1)
if direction == 1:
if rn[0]+1 == catcher[0] and rn[1] == catcher[1]:
runners[idx] = [rn[0], rn[1], rn[2], direction]
continue
runners[idx] = [rn[0]+1, rn[1], rn[2], direction]
elif direction == -1:
if rn[0]-1 == catcher[0] and rn[1] == catcher[1]:
runners[idx] = [rn[0], rn[1], rn[2], direction]
continue
runners[idx] = [rn[0]-1, rn[1], rn[2], direction]
# 술래
catcherDirection = catcher[2]
if catcherDirection == "T":
catcher = [catcher[0]-1, catcher[1], catcherDirection]
elif catcherDirection == "R":
catcher = [catcher[0], catcher[1]+1, catcherDirection]
elif catcherDirection == "D":
catcher = [catcher[0]+1, catcher[1], catcherDirection]
elif catcherDirection == "L":
catcher = [catcher[0], catcher[1]-1, catcherDirection]
if turn in changeDir:
temp = catcher[2]
if not reverse:
if temp == "T":
catcher[2] = "R"
elif temp == "R":
catcher[2] = "D"
elif temp == "D":
catcher[2] = "L"
elif temp == "L":
catcher[2] = "T"
else:
if temp == "T":
catcher[2] = "L"
elif temp == "R":
catcher[2] = "T"
elif temp == "D":
catcher[2] = "R"
elif temp == "L":
catcher[2] = "D"
if catcher[0] == 0 and catcher[1] == 0:
catcher[2] = "D"
if catcher[0] == N//2 and catcher[1] == N//2:
catcher[2] = "T"
# 시야 탐색
graphInit()
catcherDirection = catcher[2]
caught = 0
if catcherDirection == "T":
for idx in range(max(0, catcher[0]-2), catcher[0]+1):
if graph[idx][catcher[1]] == "R":
if [idx, catcher[1]] in trees:
continue
caughtPerson = findByPosition(idx, catcher[1])
if caughtPerson:
for cp in caughtPerson:
caught += 1
runners.remove(cp)
elif catcherDirection == "R":
for idx in range(catcher[1], min(N, catcher[1]+3)):
if graph[catcher[0]][idx] == "R":
if [catcher[0], idx] in trees:
continue
caughtPerson = findByPosition(catcher[0], idx)
if caughtPerson:
for cp in caughtPerson:
caught += 1
runners.remove(cp)
elif catcherDirection == "D":
for idx in range(catcher[0], min(N, catcher[0]+3)):
if graph[idx][catcher[1]] == "R":
if [idx, catcher[1]] in trees:
continue
caughtPerson = findByPosition(idx, catcher[1])
if caughtPerson:
for cp in caughtPerson:
caught += 1
runners.remove(cp)
elif catcherDirection == "L":
for idx in range(max(0, catcher[1]-2), catcher[1]+1):
if graph[catcher[0]][idx] == "R":
if [catcher[0], idx] in trees:
continue
caughtPerson = findByPosition(catcher[0], idx)
if caughtPerson:
for cp in caughtPerson:
caught += 1
runners.remove(cp)
# 점수누적
score += turn * caught
# 메인 로직
turn = 1
while turn <= K:
simulate(turn)
turn += 1
print(score)
전형적으로 단계별로 나눠서 빡세게 구현시키는
삼성 코테 문제였다.
첫번째 도망자 이동, 두번째 술래 이동, 마지막 시야 체크 후 잡기
이렇게 크게 3가지 단계
를 거쳐야 했다.
한가지 찝찝한건, 방향에 따라 조건문 분기
가 많아져서 코드가 지저분해졌는데 이 부분을 어떻게 깔끔하게 할 수 있을지다.
방향을 바꾸고, 방향에 따라 이동 시키는 로직에 대한 개선을 생각해봐야 겠다.
그렇게 되면 디버깅 과정도 한참 걸렸는데 조금 더 수월하게 디버깅할 수 있을 것 같다.
정말 잘 읽었습니다, 고맙습니다!