728x90
*문제 출처는 코드트리에 있습니다.
삼멘
문제 제목: 술래잡기
수정 한 뒤에 복사처리를 이상하게해서 계속 헤맸었다;;
문제의 코드
def run_man():
global maps
# 동시에 움직인다 술래와의 거리가 3이하면
new_maps = [[[] for n in range(n)] for i in range(n)]
for i in range(n):
for j in range(n):
if maps[i][j]:
if abs(sx - i) + abs(sy - j) <= 3: # 술래와의 거리가 3이하면 이동
tmp = deque(maps[i][j])
while tmp:
d = tmp.popleft()
ni,nj = i + direct[d][0], j + direct[d][1]
if 0 <= ni < n and 0 <= nj < n:
if ni == sx and nj == sy:
new_maps[i][j].append(d)
else:
new_maps[ni][nj].append(d)
else:
if d == 1:
d = 0
elif d == 0:
d = 1
if d == 2:
d = 3
elif d == 3:
d = 2
ndi,ndj = i + direct[d][0], j + direct[d][1]
if ndi == sx and ndj == sy:
new_maps[i][j].append(d)
else:
new_maps[ndi][ndj].append(d)
else:
new_maps[i][j] = maps[i][j][:] # 이렇게 풀면 이전에 넣어놓은 애들이 날아감 ㅠㅠ
maps = new_maps
아래처럼 바꿔줬음
new_maps[i][j] += maps[i][j]
전체 코드
from collections import deque
# 하 우 상 좌 반복
n,m,h,k = map(int,input().split())
#nxn,m 술래, h 나무, k 턴
man = [list(map(int,input().split())) for _ in range(m)]
tree = [list(map(int,input().split())) for _ in range(h)]
sx,sy = n//2,n//2
maps = [[[] for n in range(n)] for i in range(n)]
tree_maps = [[False] * n for i in range(n)]
for x,y in tree:
tree_maps[x-1][y-1] = True
direct = ((0,-1),(0,1),(1,0),(-1,0)) # 0 좌 1 우 2 하 3 상
s_direct = ((1,0),(0,1),(-1,0),(0,-1))
for x,y,d in man:
maps[x-1][y-1].append(d)
sulae_direct = [[-1] * n for i in range(n)]
def sulae_direct_map():
global s_direct
new_direct = [[-1] * n for i in range(n)]
reverse = False
if [sx,sy] == [0,0]:
reverse = True
if reverse:
s_direct = ((1, 0), (0, 1), (-1, 0), (0, -1))
else:
s_direct = ((-1, 0), (0, -1), (1, 0), (0, 1))
direction = ((1, 0), (0, 1), (-1, 0), (0, -1))
queue = deque([[0,0]])
new_direct[0][0] = 0
i = 0
while queue:
q = queue.popleft()
qx,qy = q[0],q[1]
x = qx + direction[i][0]
y = qy + direction[i][1]
if 0 <= x < n and 0 <= y < n and new_direct[x][y] == -1:
if new_direct[x][y] == -1:
new_direct[x][y] = i
queue.append([x,y])
else:
d = (i + 1) % 4
nqx = qx + direction[d][0]
nqy = qy + direction[d][1]
if 0 <= nqx < n and 0 <= nqy < n:
if new_direct[nqx][nqy] == -1:
i = d
new_direct[nqx][nqy] = i
if reverse:
new_direct[qx][qy] = i
queue.append([nqx,nqy])
return new_direct
def sulae_move():
global maps,sx,sy
d = sulae_direct[sx][sy]
nsx,nsy = sx + s_direct[d][0],sy + s_direct[d][1]
sx,sy = nsx,nsy
def get_score():
# 술래가 바라보는 방향에 3칸 이내 확인
check = []
score = 0
d = sulae_direct[sx][sy]
dx,dy = s_direct[d][0],s_direct[d][1]
if [sx,sy] == [0,0]:
dx,dy = 1,0
elif [sx,sy] == [n//2,n//2]:
dx,dy = -1,0
for i in range(3):
cx = sx + i * dx
cy = sy + i * dy
if 0 <= cx < n and 0 <= cy < n:
if tree_maps[cx][cy] == False:
check.append([cx,cy])
for x,y in check:
if maps[x][y]:
score += len(maps[x][y])
maps[x][y] = []
return score
def run_man():
global maps
# 동시에 움직인다 술래와의 거리가 3이하면
new_maps = [[[] for n in range(n)] for i in range(n)]
for i in range(len(maps)):
for j in range(len(maps)):
if maps[i][j]:
if abs(sx - i) + abs(sy - j) <= 3: # 술래와의 거리가 3이하면 이동
tmp = deque(maps[i][j])
while tmp:
d = tmp.popleft()
ni,nj = i + direct[d][0], j + direct[d][1]
if 0 <= ni < len(maps) and 0 <= nj < len(maps):
if ni == sx and nj == sy:
new_maps[i][j].append(d)
else:
new_maps[ni][nj].append(d)
else:
if d == 1:
d = 0
elif d == 0:
d = 1
if d == 2:
d = 3
elif d == 3:
d = 2
ndi,ndj = i + direct[d][0], j + direct[d][1]
if ndi == sx and ndj == sy:
new_maps[i][j].append(d)
else:
new_maps[ndi][ndj].append(d)
else:
new_maps[i][j] += maps[i][j]
maps = new_maps
time = 1
answer = 0
while k > 0:
if [sx,sy] == [n//2,n//2] or [sx,sy] == [0,0]:
sulae_direct = sulae_direct_map()
run_man()
sulae_move()
score = get_score()
answer += time * score
k -= 1
time += 1
print(answer)
술래가 갈 좌표는 달팽이처럼 업데이트 해주면 된다.
제발!! 실수하지말고!! 복사처리 애매하게 하지말자!!!으아아아악!!!!!
https://sillon-coding.tistory.com/615
수정 전 풀이
더보기
from collections import deque
# 하 우 상 좌 반복
n,m,h,k = map(int,input().split())
#nxn,m 술래, h 나무, k 턴
man = [list(map(int,input().split())) for _ in range(m)]
man_num = m # 술래 수
tree = [list(map(int,input().split())) for _ in range(h)]
# 도망자 위치와 이동방법 (x,y,d) //
tree_maps = [[0] * n for _ in range(n)]
for x,y in tree:
tree_maps[x-1][y-1] = 1
sulae_maps = [[-1] * n for _ in range(n)]
s_direct = ((-1,0),(0,1),(1,0),(0,-1))
sx,sy = n//2,n//2
maps = [[0]*n for _ in range(n)]
def run_man(): # 도망자들
for i in range(len(man)):
x,y,d = man[i]
dist = abs(x - sx) + abs(y - sy)
dx,dy = d[0],d[1]
if dist <= 3:
if 0 <= dx + x < n and 0 <= dy + y < n:
if [dx+x,dy+y] == [sx,sy]:
# 움직이려는 칸에 술래가 있으면 움직이지 않는다
continue
maps[x][y] -= 1
maps[dx+x][dy+y] += 1
man[i] = [dx+x,dy+y,d]
else: # 범위를 벗어나면 방향 틀기
dx, dy = dx * -1,dy * -1
if [dx+x,dy+y] == [sx,sy]:
# 움직이려는 칸에 술래가 있으면 움직이지 않는다
# man[i] = [dx+x,dy+y,d] TODO: 나중에 확인
continue
maps[x][y] -= 1
maps[dx+x][dy+y] += 1
man[i] = [dx+x,dy+y,[dx,dy]]
return
def move_man(): # 술래
global sx,sy,s_direct, man_num
if [sx,sy] == [n//2, n// 2 ]:
s_direct = ((-1,0),(0,-1),(1,0),(0,1))
# 초기 술래 방향 세팅
sulae_direction(reverse = False)
elif [sx,sy] == [0,0]:
s_direct = ((1, 0), (0, 1), (-1, 0), (0, -1))
# 반대방향으로 술래 방향 세팅
sulae_direction(reverse = True)
d = sulae_maps[sx][sy]
dx,dy = s_direct[d][0], s_direct[d][1]
sx,sy = dx + sx, dy + sy
tmp = []
cnt = 0
if maps[sx][sy] > 0 and tree_maps[sx][sy] != 1:
tmp.append([sx,sy])
cnt += maps[sx][sy]
print('술래',sx,sy)
for i in maps:
print(i)
return tmp,cnt
def score(tmp):
global man
# 시야 내에 나무가 있는지 확인
# 시야는 3칸 (술래 위치 포함해서)
# 술래는 방향을 틀자마자 시야 내에 도망자가 있으면 잡는다
d = sulae_maps[sx][sy]
dx,dy = s_direct[d][0], s_direct[d][1]
cnt2 = 0
for i in range(1,3):
nx = sx + dx * i
ny = sy + dy * i
if 0 <= nx < n and 0 <= ny < n:
if tree_maps[nx][ny] != 1 and maps[nx][ny] > 0:
cnt2 += maps[nx][ny]
maps[nx][ny] = 0
tmp.append([nx,ny])
tmp_man = []
if tmp:
for x,y,d in man:
for tx,ty in tmp:
if x != tx and y != ty:
tmp_man.append([x,y,d])
man = tmp_man
return cnt2
def sulae_direction(reverse):
global sulae_maps
direction = ((1,0),(0,1),(-1,0),(0,-1))
queue = deque([[0,0,0]])
sulae_maps = [[-1] * n for _ in range(n)]
while queue:
qx, qy, qd = queue.popleft()
d = qd % 4
sulae_maps[qx][qy] = qd
xx, yy = qx + direction[d][0], qy + direction[d][1]
if 0 <= xx < n and 0 <= yy < n and sulae_maps[xx][yy] == -1:
queue.append([xx, yy,qd])
else:
d = (qd + 1) % 4
dx, dy = direction[d][0], direction[d][1]
if 0 <= qx + dx < n and 0 <= qy + dy < n and sulae_maps[qx + dx][qy + dy] == -1:
if reverse == True:
sulae_maps[qx][qy] = d # 방향 바뀌면 처리
queue.append([qx + dx, qy + dy, d])
# 초기 도망자 방향 세팅
for i in range(m):
man[i][0] -= 1
man[i][1] -= 1
maps[man[i][0]][man[i][1]] += 1
if man[i][2] == 1:
man[i][2] = [0,1]
elif man[i][2] == 2:
man[i][2] = [1,0]
time = 1
answer = 0
print('초기맵')
for i in maps:
print(i)
while k > 0:
# if 술래 위치 중앙:
# 방향 튼다 direction =
# elif 술래 위치 좌상단:
# 방향튼다
# TODO: (0,0)에 도착 하자마자 방향이 바뀌어야함
run_man() # 도망자들
# print(time,'도망자 이동')
# for i in maps:
# print(i)
tmp, cnt = move_man() # 술래 움직임
cnt2 = score(tmp)
answer += (cnt + cnt2) * time
man_num -= (cnt + cnt2)
k -= 1
time += 1
print(answer)
문제가 된 부분
- 처음에 나무가 있고, 술래가 있고, 도망자가 같이있을때,
나무가 있으면 술래의 시야에 가려져서 도망자는 잡히지 않는다. -> 해결
술래는 잘 움직이는데 도망자들이 겹쳐져있을때 로직이 제대로 구현 안됐음 -> 미해결..
다른 코드는 그냥 도망자의 방향 자체만 계속 리스트에 넣어 업데이트 해주는 형식을 씀
아래처럼..
다시 풀어보자..
※ 알아야 할 것
- 복사처리 이상하게 하지말자........................... 리스트는 항상 조심 또 조심
728x90
'coding test - python > SAMSUNG SWT(SW역량 테스트)' 카테고리의 다른 글
삼성 기출 정리 (0) | 2024.10.12 |
---|---|
삼성 SW역량테스트 기출 / 2022 하반기 오후 1번 문제 코드트리 빵 / Python 파이썬 (5) | 2024.10.11 |
삼성 SW역량테스트 기출 / 2023 상반기 오후 1번 문제 메이즈러너 - 회전, BFS, 가장 작은 정사각형 찾고 회전 / Python 파이썬 (4) | 2024.10.09 |
달팽이 너같은거... (5) | 2024.10.09 |
삼성 SW역량테스트 기출 / 2023 상반기 오전 1번 문제 포탑부수기 - BFS (조건문 확인 계속하기) / Python 파이썬 (13) | 2024.10.08 |