삼성 SW 역량 테스트 기출 문제
# 정답 코드
n, m, k = map(int, input().split())
board = [ [ [0] for _ in range(n+1) ] for _ in range(n+1) ]
pboard = [ [ [] for _ in range(n+1) ] for _ in range(n+1) ]
player = [ [] for _ in range(m+1) ]
score = [ 0 for _ in range(m) ]
for i in range(1, n+1):
inl = list(map(int, input().split()))
for l in range(len(inl)):
board[i][l+1] = [ inl[l] ]
for i in range(1, m+1):
inl = list(map(int, input().split()))
player[i] = inl+[0]
for i in range(1, m+1):
pboard[player[i][0]][player[i][1]] = [ i ]
def fisrt_move(mover, x, y, d, inlose=False):
nx, ny = x, y
# 한칸 이동
if d == 0: # 북
nx = x - 1
# ny = y
if d == 1: # 동
# nx = x
ny = y + 1
if d == 2: # 남
nx = x + 1
# ny = y
if d == 3: # 서
# nx = x
ny = y - 1
# 만약 이동한 칸이 범위를 벗어나면,
## 방향 반대로 바꾸기
if nx > n: # and 1 <= ny <= n:
d = 0 # 3 # 0
elif ny > n: # and 1 <= nx <= n:
d = 3 # 0 # 3
elif nx < 1: # and 1 <= ny <= n:
d = 2 # 1 # 2
elif ny < 1: # and 1 <= nx <= n:
d = 1 # 2 # 1
else:
return nx, ny
# 그리고 한칸 이동
if d == 0: # 북
nx = x - 1
ny = y
if d == 1: # 동
nx = x
ny = y + 1
if d == 2: # 남
nx = x + 1
ny = y
if d == 3: # 서
nx = x
ny = y - 1
player[mover][2] = d
return nx, ny
def move(mover, x, y, d, inlose=False):
nx, ny = x, y
if d == 0: # 북
nx = x - 1
ny = y
if d == 1: # 동
nx = x
ny = y + 1
if d == 2: # 남
nx = x + 1
ny = y
if d == 3: # 서
nx = x
ny = y - 1
return nx, ny
def peace(mover, mx, my):
cur = player[mover][4] # 현재 총의 공격력
max = 0
gun_list = board[mx][my] # 좌표의 총 리스트
rest = []
if len(gun_list) != 0: # if gun_list[0] != 0: # 총이 하나라도 있으면
gun_list.append(cur) # 있던총, 내려놓은 총들
gun_list.sort(reverse=True) # 내림차순해서 가장 큰걸 앞으로
player[mover][4] = gun_list[0] # 젤 큰거 가지기
board[mx][my] = gun_list[1:] # 나머지는 두기
def lose(loser, x, y):
inlose = True
if player[loser][4] != 0: # 수중에 있던 총 내려놓기
if board[x][y] == [0]:
board[x][y] = [ player[loser][4] ]
else:
board[x][y].append(player[loser][4])
player[loser][4] = 0
while True:
nx, ny = move(loser, player[loser][0], player[loser][1], player[loser][2], inlose)
# 격자 밖이거나 다른 사람 있으면 빈칸 보일때까지 90도 돌리기
if nx<1 or nx>n or ny<1 or ny>n or len(pboard[nx][ny]) != 0:
player[loser][2] += 1
if player[loser][2] > 3:
player[loser][2] = 0
else:
pboard[nx][ny].append(loser) # 새로 좌표 바꾸기
pboard[x][y].remove( loser ) # pboard[x][y] = []
player[loser][0] = nx
player[loser][1] = ny
##### ** 여기에서 중요 ** #####
### 그냥 peace를 부르면 안된다.
### 이미 총을 내려둔 상태이기에 총은 0개 들고 있음
### 따라서 자신의 것을 또 내려놓을 필요가 없다.
### 이동한 좌표에 있는 총 중에
# peace(loser, nx, ny) # 총 줍기
# cur = player[loser][4] # 현재 총의 공격력
gun_list = board[nx][ny]
if len(gun_list) != 0: # if gun_list[0] != 0:
# gun_list.append(cur)
gun_list.sort(reverse=True)
player[loser][4] = gun_list[0]
board[nx][ny] = gun_list[1:]
break
def win(winner, x, y):
# pboard[x][y] = [winner]
peace(winner, x, y)
def fight(hum1, hum2, x, y):
# sc = 0
p1 = player[hum1][3]+player[hum1][4]
p2 = player[hum2][3]+player[hum2][4]
if p1 > p2:
lose(hum2, x, y)
pboard[x][y] = [hum1]
win(hum1, x, y)
sc = p1 - p2
score[hum1-1] += sc
elif p1 < p2:
lose(hum1, x, y)
pboard[x][y] = [hum2]
win(hum2, x, y)
sc = p2 - p1
score[hum2-1] += sc
elif p1==p2:
if player[hum1][3] > player[hum2][3]:
lose(hum2, x, y)
pboard[x][y] = [hum1]
win(hum1, x, y)
sc = p1 - p2
score[hum1 - 1] += sc
if player[hum1][3] < player[hum2][3]:
lose(hum1, x, y)
pboard[x][y] = [hum2]
win(hum2, x, y)
sc = p2 - p1
score[hum2 - 1] += sc
for kk in range(k):
# 1. 모든 사람 이동
for p in range(1, m+1):
x = player[p][0]
y = player[p][1]
# 새 좌표로 이동
nx, ny = fisrt_move(p, x, y, player[p][2])
player[p][0] = nx
player[p][1] = ny
pboard[x][y].remove( p ) # pboard[x][y] = []
pboard[nx][ny].append( p )
# 2. 평화 혹은 싸움
if len(pboard[nx][ny]) == 1: # 한명 있으면
peace(pboard[nx][ny][0], nx, ny)
else: # 두명 있으면
fight(pboard[nx][ny][0], pboard[nx][ny][1], nx, ny)
for _ in score:
print(_, end=' ')