Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'''

1. 아이디어
- C개의 공유기를 N개의 집에 설치해서, 가장 인접한 두 공유기 사이의 거리 중 최댓값.
- 가장 인접한 두 공유기 사이의 거리를 구하기 위해 최소거리를 설정하고, 그 최소거리만큼 띄워서 공유기 설치
- 설치한 공유기가 c개 미만이면 최소거리를 낮춤, 설치한 공유기가 c개 이상이면 최소거리를 늘림.(최댓값을 찾기 위해서)
- 이분탐색 알고리즘을 사용하여 '(1, 가장 오른쪽 집 - 가장 왼쪽 집)' 범위에서 최소거리 찾기
2. 시간 복잡도
- N(2<= N <= 200,000), M(2 <= M <= N) 일때,
완전탐색으로 N개의 집 중 공유기를 설치할 M개를 조합하는 시간복잡도는 O(NCM)이고
조합한 배열에서 인접한 두 공유기 사이의 거리를 구하는 것은 O(M-1)이므로 O(NCM * (M-1))은 시간 초과.
- 이분탐색은 O(N*logN)이므로 N이 200,000일때도 가능.

3. 구현
3-1. 입력받기
3-2. 배열 정렬
3-3. 이분탐색
- start, end, 를 각각 1과 arr[n-1] - arr[0]로 초기화.
- 공유기를 최소거리만큼 띄워서 설치.
- 설치 공유기 개수가 c보다 작으면 end를 mid로 설정.
- 설치 공유기 개수가 c이상이면 start를 mid+1로 설정.
- start와 end가 교차하면 종료

'''

import sys

inp = sys.stdin.readline


def install_router(mid):
# 가장 왼쪽의 집은 무조건 설치
router_count = 1
previous_house = house[0]

# 이전에 공유기를 설치했던 집 좌표 + mid <= 현재 집 좌표인지 확인
for i in range(N):
if previous_house + mid <= house[i]:
router_count += 1
previous_house = house[i]

return router_count


# 입력받기
N, C = map(int, inp().split())
house = list(map(int, [inp() for _ in range(N)]))

# 정렬
house.sort()

# 인접한 두 집의 가능한 최소거리와 최대거리
start = 1
end = house[N - 1] - house[0]

# 정답
answer = 0

while start <= end:
# 이분탐색을 위한 mid
mid = (start + end) // 2

# 설치한 공유기 개수를 반환
router_count = install_router(mid)

if router_count >= C:
start = mid + 1
answer = mid
else:
end = mid - 1

print(answer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'''

1.하나의 옵션에 대해 왼쪽에서부터 오른쪽 순서로 단어의 첫 글자가(공백으로 구분하는 것을 이용) 이미 단축키로 지정되었는지 살펴본다.
만약 단축키로 아직 지정이 안 되어있다면 그 알파벳을 단축키로 지정한다.

2. 만약 모든 단어의 첫 글자가 이미 지정이 되어있다면 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.

3.어떠한 것도 단축키로 지정할 수 없다면 그냥 놔두며 대소문자를 구분치 않는다.

4. 위의 규칙을 첫 번째 옵션부터 N번째 옵션까지 차례대로 적용한다.

'''

import sys

inp = sys.stdin.readline

N = int(inp())

# 단축키로 지정된 대문자 알파벳들
used_shortcuts = set()

# 결과 저장용 리스트
results = []

for _ in range(N):
original = inp().strip()
shortcut_index = -1
words = original.split()
index_in_string = 0

# 1단계: 각 단어의 첫 글자 확인
for word in words:
char = word[0].upper()
if char not in used_shortcuts:
used_shortcuts.add(char)
shortcut_index = index_in_string
Copy link
Collaborator

Choose a reason for hiding this comment

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

boolean 변수가 아니라 인덱스를 저장하는 변수를 두어서 접근하여, 마지막에 인덱스가 -1이 아닌 경우에만 마크 표시를 하는 것이 인상적이었습니다!

break
index_in_string += len(word) + 1 # 공백 포함해서 다음 인덱스 계산

# 2단계: 전체 문자열 순회
if shortcut_index == -1:
for i, char in enumerate(original):
if char != ' ' and char.upper() not in used_shortcuts:
used_shortcuts.add(char.upper())
shortcut_index = i
break

# 단축키 표시
if shortcut_index != -1:
marked = (
original[:shortcut_index]
+ '[' + original[shortcut_index] + ']'
+ original[shortcut_index + 1:]
)
results.append(marked)
else:
results.append(original)
Comment on lines +49 to +58
Copy link
Collaborator

Choose a reason for hiding this comment

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

그리고 입력받은 값을 바로바로 출력하는 것이 아니라 result에 저장해두고, 마지막에 하나씩 출력하는 것도 인상 깊었어요! 참고가 되었습니다 :D


# 출력
print('\n'.join(results))
72 changes: 72 additions & 0 deletions YoonYn9915/implementation/2025-05-17-[백준]-#2564-경비원.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'''
1. 아이디어
- 방향이 두가지이고 최소거리는 둘레 // 2 보다 작거나 같아야 하므로, 시계방향 거리를 구해서 둘레 // 2와 비교하며 처리하자
- 동근이와 상점의 시계방향 거리를 구할때는 (0,0)을 기준점으로 잡고 기준점부터 동근이의 거리, 기준점부터 상점의 거리를 구한 후 차이를 구하자

2. 시간복잡도
상점 위치 입력 → O(nums)
거리 계산 → O(nums)
최대 O(100)로 1초안에 가능 (n이 100이하니까)

3. 구현
3-1. 입력 받기
3-2. 전체 둘레 계산
3-3. 시계 방향으로 거리 계산 함수 정의
3-4. (0,0)에서부터 시계방향으로 동근이와 상점의 거리 구하기
3-5. 3-4를 기반으로 시계방향으로 동근이와 상점의 거리 구하기
3-6. 시계방향 거리가 전체 둘레의 절반보다 작다면 시계방향을 더하고, 크다면 반시계방향 거리 더하기
3-7. 결과 출력
'''

import sys

inp = sys.stdin.readline

row, col = map(int, inp().strip().split())

# 전체 둘레
round_length = row * 2 + col * 2
answer = 0

# 동근이의 위치와 상점의 좌표 저장
locations = []
n = int(inp().strip())

for _ in range(n + 1):
dir, num = map(int, inp().strip().split())
locations.append((dir, num))


def calculate_distance(dir, num):
if dir == 1:
return num
elif dir == 2:
return row + col + (row - num)
elif dir == 3:
return row + col + row + (col - num)
else:
return row + num


for i in range(n):
# 동근이 좌표
dir, num = locations[n]

# 상점 좌표
store_dir, store_num = locations[i]

# (0,0)에서부터 시계방향으로 동근이의 거리
d1 = calculate_distance(dir, num)

# (0,0)에서부터 시계방향으로 상점의 거리
d2 = calculate_distance(store_dir, store_num)

# 시계방향 동근이 - 상점간 거리
distance = abs(d2 - d1)

if distance < round_length // 2:
answer += distance
else:
answer += round_length - distance
Comment on lines +67 to +70
Copy link
Collaborator

Choose a reason for hiding this comment

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

저는 min()함수를 썼는데 이런 조건식으로 접근할 수도 있는 것, 알아갑니다!


print(answer)