https://www.codetree.ai/frequent-problems/tail-catch-play/description
코드트리
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
# 꼬리잡기놀이
def move(temp_list):
# 머리 수정
head_r = temp_list[0][0]
head_c = temp_list[0][1]
for i in range(4):
cr = head_r + dr[i]
cc = head_c + dc[i]
if 0 <= cr < N and 0 <= cc < N and (grounds[cr][cc] == 4 or grounds[cr][cc] == 3):
grounds[cr][cc] = 1
temp_list.insert(0, [cr, cc])
# 꼬리 수정
tail_r, tail_c = temp_list.pop()
for i in range(4):
cr = tail_r + dr[i]
cc = tail_c + dc[i]
if 0 <= cr < N and 0 <= cc < N and grounds[cr][cc] == 2:
if grounds[tail_r][tail_c] == 3:
grounds[tail_r][tail_c] = 4
grounds[cr][cc] = 3
grounds[head_r][head_c] = 2
return
def change_head_tail(temp_list):
before_head_r, before_head_c = temp_list[0]
before_tail_r, before_tail_c = temp_list[-1]
temp_list = temp_list[::-1]
grounds[before_head_r][before_head_c] = 3
grounds[before_tail_r][before_tail_c] = 1
return temp_list
def get_score(temp_r, temp_c):
if grounds[temp_r][temp_c] == 1:
return 1
elif grounds[temp_r][temp_c] == 3:
for i in range(len(teams)):
if [find_r, find_c] in teams[i]:
return len(teams[i])
queue = [[temp_r, temp_c, 1]]
visited = [[0] * N for _ in range(N)]
visited[temp_r][temp_c] = 1
while queue:
qr, qc, qdis = queue.pop(0)
for i in range(4):
cr = qr + dr[i]
cc = qc + dc[i]
if 0 <= cr < N and 0 <= cc < N and 0 < grounds[cr][cc] < 3 and visited[cr][cc] == 0:
visited[cr][cc] = 1
queue.append([cr, cc, qdis + 1])
if grounds[cr][cc] == 1:
return qdis + 1
return 0
# 상 좌 하 우
dr = [-1, 0, 1, 0]
dc = [0, -1, 0, 1]
N, M, K = map(int, input().split())
grounds = [list(map(int, input().split())) for _ in range(N)]
teams = list()
total_score = 0
# 팀 리스트 구하기
for r in range(N):
for c in range(N):
if grounds[r][c] == 1:
temp_list = [[r, c]]
queue = [[r, c]]
visited = [[0] * N for _ in range(N)]
visited[r][c] = 1
temp_tail_r = -1
temp_tail_c = -1
while queue:
qr, qc = queue.pop(0)
for i in range(4):
cr = qr + dr[i]
cc = qc + dc[i]
if 0 <= cr < N and 0 <= cc < N and visited[cr][cc] == 0:
if 0 < grounds[cr][cc] < 3:
visited[cr][cc] = 1
temp_list.append([cr, cc])
queue.append([cr, cc])
elif grounds[cr][cc] == 3:
temp_tail_r, temp_tail_c = cr, cc
temp_list.append([temp_tail_r, temp_tail_c])
teams.append(temp_list)
# 현재 공이 던져지는 방향은 우측
cur_direction = 3
cur_r = 0
cur_c = 0
for idx_K in range(K):
# 1. 각 팀은 머리사람을 따라서 한 칸 이동
for te in teams:
move(te)
# 2. 각 라운드마다 공이 정해진 선을 따라 던져진다.
find_r = -1
find_c = -1
queue = [[cur_r, cur_c]]
# 그 자리에서 찾았다면
if 0 < grounds[cur_r][cur_c] < 4:
find_r = cur_r
find_c = cur_c
else:
while queue:
qr, qc = queue.pop(0)
cr = qr + dr[cur_direction]
cc = qc + dc[cur_direction]
if 0 <= cr < N and 0 <= cc < N:
# 아직 못만남
if grounds[cr][cc] == 0 or grounds[cr][cc] == 4:
queue.append([cr, cc])
# 만남
else:
find_r = cr
find_c = cc
break
# 다음 반복문을 위해 이동
round_direction = (cur_direction - 1) % 4
temp_r = cur_r + dr[round_direction]
temp_c = cur_c + dc[round_direction]
# 이동 이후 범위 안에 있다면
if 0 <= temp_r < N and 0 <= temp_c < N:
cur_r = temp_r
cur_c = temp_c
# 범위 밖이라면 방향만 변경
else:
cur_direction = (cur_direction + 1) % 4
# 찾았다면
if find_r != -1:
cur_score = get_score(find_r, find_c)
total_score += (cur_score ** 2)
# 찾은 팀의 꼬리와 머리 바꾸어야 함
for i in range(len(teams)):
if [find_r, find_c] in teams[i]:
teams[i] = change_head_tail(teams[i])
break
print(total_score)
"""
예제 3 틀렸습니다.
7 3 5
3 2 1 0 0 0 0
4 0 4 0 2 1 4
4 4 4 0 2 0 4
0 0 0 0 3 4 4
2 1 3 2 0 0 0
2 0 0 2 0 0 0
2 2 2 2 0 0 0
현지 조건에서는 1, 3 안붙어있었음
코드트리를 위해 코드 수정
get_score에서 1(머리) 만났을 때 로직 수정
get_score에서 맨 마지막에 return 0 추가
예제 4 틀렸습니다.
get_score에서 3(꼬리) 만났을 때 로직 수정
"""
'프로그래밍 > 문제풀이' 카테고리의 다른 글
[Python] 백준 16236 아기 상어 (0) | 2022.10.14 |
---|---|
[Python] 백준 21610 마법사 상어와 비바라기 (0) | 2022.10.14 |
[Python] 코드트리 2022-1 오전 예술성 (0) | 2022.10.14 |
[Python] 백준 21609 상어 중학교 (0) | 2022.10.13 |
[Python] 백준 21608 상어 초등학교 (0) | 2022.10.12 |