Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[장희직] - 왕실의 기사 대결, 메이즈 러너, 귤 고르기, 아이템 줍기 #238

Merged
merged 1 commit into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/kotlin/heejik/57week/귤 고르기.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from collections import defaultdict


def solution(k, tangerines):
limit = k

tan_cnt = defaultdict(int)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파이썬이 진짜 좋네요


for tangerine in tangerines:
tan_cnt[tangerine] += 1
sorted_tan_cnt = sorted(tan_cnt.values(), reverse=True)
for idx, tan_cnt in enumerate(sorted_tan_cnt):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enumerate 안쓰면 안되는건가요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 알기론 enumerate 써야 index 같이 추출하는 걸로 알고 있어요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enumerate로 idx쓰는게 깔끔하네요!

limit -= tan_cnt
if limit <= 0:
return idx + 1
127 changes: 127 additions & 0 deletions src/main/kotlin/heejik/57week/메이즈 러너.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]
sum_move_distance = 0


def get_distance(x1, y1, x2, y2):
return abs(x1 - x2) + abs(y1 - y2)


def solve():
for _ in range(k):
move()
if len(man_pos) == 0:
break
rotate()
# for row in board:
# print(row)
# print("----------------------------")
print(sum_move_distance)
print(exit_pos[0] + 1, exit_pos[1] + 1)


def move():
global sum_move_distance, man_pos
# 사람 한 명씩
pop_idx = []
for idx, [x, y] in enumerate(man_pos):
# 4 방향을 돌며
dir = -1
dis = get_distance(x, y, exit_pos[0], exit_pos[1])
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx not in range(n) or ny not in range(n): continue
if board[nx][ny] != 0: continue
# print(idx, i)
distance = get_distance(nx, ny, exit_pos[0], exit_pos[1])
if distance <= dis:
dis = distance
dir = i
# print(dir)
if dir == -1: continue
if [x + dx[dir], y + dy[dir]] == exit_pos:
pop_idx.append(idx)
else:
man_pos[idx] = [x + dx[dir], y + dy[dir]]
sum_move_distance += 1

man_pos = [item for idx, item in enumerate(man_pos) if idx not in pop_idx]
# for idx in pop_idx:
# man_pos.pop(idx)


def rotate():
global exit_pos, man_pos
x1, y1, x2, y2 = find_small_rect()
offset_x = x1
offset_y = y1
Comment on lines +57 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오프셋 처리를 저도 해봐야겠네요

# print("find_small_rect", find_small_rect())
n_rect = [[0 for _ in range(x2 - x1 + 1)] for _ in range(x2 - x1 + 1)]

offset = x2 - x1
# print(man_pos)
tmp_man = []
tmp_exit = []
for x in range(offset + 1):
for y in range(offset + 1):
pre_x = x + offset_x
pre_y = y + offset_y
new_x = y
new_y = abs((x2 - x1) - x)
# print(pre_x, pre_y, new_x, new_y)
n_rect[new_x][new_y] = board[pre_x][pre_y]
while True:
if [pre_x, pre_y] in man_pos:
man_pos.remove([pre_x, pre_y])
tmp_man.append([new_x + offset_x, new_y + offset_y])
else:
break
if [pre_x, pre_y] == exit_pos:
tmp_exit = [new_x + offset_x, new_y + offset_y]

man_pos.extend(tmp_man)
if len(tmp_exit) != 0: exit_pos = tmp_exit
# print(n_rect)
# print("exit_pos:", exit_pos)
# print("man_pos:", man_pos)
for x in range(x1, x2 + 1):
for y in range(y1, y2 + 1):
board[x][y] = max(0, n_rect[x - offset_x][y - offset_y] - 1)


def find_small_rect():
offset = 0
while True:
offset += 1
for x in range(n - offset):
for y in range(n - offset):
if can_rect(x, y, x + offset, y + offset):
return [x, y, x + offset, y + offset]


# x1 = 작은 x, y1 = 작은 y, x2 = 큰 x, y2 = 큰 y
def can_rect(x1, y1, x2, y2):
is_in_man = False
is_in_exit = False
for x in range(x1, x2 + 1):
for y in range(y1, y2 + 1):
if exit_pos == [x, y]: is_in_exit = True
if [x, y] in man_pos: is_in_man = True

return is_in_man and is_in_exit


n, m, k = 0, 0, 0
board = []
man_pos = []
exit_pos = []

if __name__ == '__main__':
n, m, k = map(int, input().split())
for _ in range(n):
board.append(list(map(int, input().split())))
for _ in range(m):
man_pos.append(list(map(lambda x: int(x) - 1, input().split())))
exit_pos = list(map(lambda x: int(x) - 1, input().split()))
solve()
54 changes: 54 additions & 0 deletions src/main/kotlin/heejik/57week/아이템 줍기.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from collections import deque

board = [[0 for _ in range(101)] for _ in range(101)]
# 상하좌우
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]


def solution(_rectangle, character_x, character_y, item_x, item_y):
rectangle = map(lambda x: list(map(lambda y: y * 2, x)), _rectangle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

덕분에 어떻게 풀어야하는지를 깨닫게 되었어요!

for (x1, y1, x2, y2) in rectangle:
for x in range(x1, x2 + 1):
board[x][y1] = max(1, board[x][y1])
board[x][y2] = max(1, board[x][y2])
for y in range(y1, y2 + 1):
board[x1][y] = max(1, board[x1][y])
board[x2][y] = max(1, board[x2][y])
for x in range(x1 + 1, x2):
for y in range(y1 + 1, y2):
board[x][y] = 2

answer = bfs(character_x * 2, character_y * 2, item_x * 2, item_y * 2)

return answer


def bfs(character_x, character_y, item_x, item_y):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 bfs로 탐색해도 갈 수가 있군요.....

queue = deque()
queue.append([character_x, character_y, 0])
board[character_x][character_y] = 2

while len(queue) != 0:
(x, y, cnt) = queue.popleft()
if x == item_x and y == item_y: return cnt // 2
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx not in range(1, 101) or ny not in range(1, 101): continue
if board[nx][ny] != 1: continue
queue.append([nx, ny, cnt+1])
board[nx][ny] = 2

return 0


# 시작점에서 사이드, 위아래 우선순위는 제거
# 내부 중간 여백 빈 공간 어떻게 없앨지 고민 지금 코드는 존재함
if __name__ == '__main__':
print(solution(_rectangle=[[1, 1, 8, 4], [2, 2, 4, 9], [3, 6, 9, 8], [6, 3, 7, 7]],
character_x=9,
character_y=7,
item_x=6,
item_y=1
))
130 changes: 130 additions & 0 deletions src/main/kotlin/heejik/57week/왕실의 기사 대결.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

l, n, q = 0, 0, 0
board: list = []
knight_pos = [] # 기사들의 위치가 배열 index 에 존재
knight_hp = []
knight_origin_hp = []
board_pos = [] # 기사들의 위치가 l*l 보드 형식으로 존재
moved_pos = []


def move(origin_number, number, d):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

왜인지는 모르겠지만 dfs로 풀면 힘들겠다고 생각했는데, dfs로도 잘 푸는 방법을 보게 되어 좋았습니다!

print("number:", number, "origin_number:", origin_number, "d:", d)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 이거 남겨도 혹시 정답처리가 되나요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아닙니다 ㅠㅠ 제출할 땐 제거했었어요 ㅠ

global moved_pos
can_move = True
for x, y in knight_pos[number]:
nx = x + dx[d]
ny = y + dy[d]
if nx not in range(l) or ny not in range(l) or board[nx][ny] == 2:
return False

new_number = []
for x, y in knight_pos[number]:
nx = x + dx[d]
ny = y + dy[d]
if board_pos[nx][ny] != -1 and board_pos[nx][ny] != number:
new_number.append(board_pos[nx][ny])
for n_number in set(new_number):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요러면 요 포문에서 순회할 때 new_number가 리스트가 아닌 셋처럼 동작하는건가요???

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옙!!👍

if can_move:
can_move = move(origin_number=origin_number, number=n_number, d=d)

if can_move:
for x, y in knight_pos[number]:
nx = x + dx[d]
ny = y + dy[d]
moved_pos[number].append([nx, ny])

if number == origin_number:
for num in range(n):
if len(moved_pos[num]) == 0: continue
pre_pos = knight_pos[num].copy()
knight_pos[num].clear()
for x, y in pre_pos:
if board_pos[x][y] == num:
board_pos[x][y] = -1
for nx, ny in moved_pos[num]:
board_pos[nx][ny] = num
knight_pos[num].append([nx, ny])
if num != origin_number:
get_damage(pushed_out_number=num)

if number == origin_number:
moved_pos = list(map(lambda x: list(), moved_pos))

return can_move


def get_damage(pushed_out_number: int):
is_deleted = False
for x, y in knight_pos[pushed_out_number]:
if board[x][y] == 1:
knight_hp[pushed_out_number] -= 1
if knight_hp[pushed_out_number] == 0:
is_deleted = True
break

if is_deleted:
for x, y in knight_pos[pushed_out_number]:
board_pos[x][y] = -1
knight_pos[pushed_out_number].clear()


def solve():
global l, n, q, board, knight_pos, knight_hp, board_pos, moved_pos
l, n, q = map(int, input().split())
moved_pos = [[] for _ in range(n)]

for _ in range(l):
board.append(list(map(int, input().split())))
board_pos.append([-1 for _ in range(l)])
for number in range(n):
r, c, h, w, k = map(int, input().split())
knight_hp.append(k)
knight_origin_hp.append(k)
pos = []
for i in range(r - 1, r - 1 + h):
for j in range(c - 1, c - 1 + w):
pos.append([i, j])
board_pos[i][j] = number

knight_pos.append(pos)

for e in board_pos:
print(e)
for idx, w in enumerate(knight_pos):
print(str(idx) + "번 기사의 위치는: ", w)
print("남은 체력:", knight_hp)
print("--------------")

for _ in range(q):
i, d = map(int, input().split())
move(origin_number=i - 1, number=i - 1, d=d)
for q in board_pos:
print(q)
for idx, w in enumerate(knight_pos):
print(str(idx) + "번 기사의 위치는: ", w)
print("남은 체력:", knight_hp)
print("--------------")
answer = 0
for idx, hp in enumerate(knight_hp):
if hp > 0:
answer += (knight_origin_hp[idx] - knight_hp[idx])

print(answer)


if __name__ == '__main__':
# a = set()
# a.add(6)
# a.add(6)
# a.add(3)
# a.add(6)
# print(a)
#
# for q in a:
# print(q)
solve()

#