Skip to content

Commit 7a12ae7

Browse files
authored
Merge pull request #209 from AlgorithmStudy-Allumbus/YoonYn9915
YoonYn9915/ 5월 2주차/ 3문제
2 parents a8fc53a + 196c0a0 commit 7a12ae7

File tree

3 files changed

+205
-0
lines changed

3 files changed

+205
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'''
2+
3+
1. 아이디어
4+
- C개의 공유기를 N개의 집에 설치해서, 가장 인접한 두 공유기 사이의 거리 중 최댓값.
5+
- 가장 인접한 두 공유기 사이의 거리를 구하기 위해 최소거리를 설정하고, 그 최소거리만큼 띄워서 공유기 설치
6+
- 설치한 공유기가 c개 미만이면 최소거리를 낮춤, 설치한 공유기가 c개 이상이면 최소거리를 늘림.(최댓값을 찾기 위해서)
7+
- 이분탐색 알고리즘을 사용하여 '(1, 가장 오른쪽 집 - 가장 왼쪽 집)' 범위에서 최소거리 찾기
8+
2. 시간 복잡도
9+
- N(2<= N <= 200,000), M(2 <= M <= N) 일때,
10+
완전탐색으로 N개의 집 중 공유기를 설치할 M개를 조합하는 시간복잡도는 O(NCM)이고
11+
조합한 배열에서 인접한 두 공유기 사이의 거리를 구하는 것은 O(M-1)이므로 O(NCM * (M-1))은 시간 초과.
12+
- 이분탐색은 O(N*logN)이므로 N이 200,000일때도 가능.
13+
14+
3. 구현
15+
3-1. 입력받기
16+
3-2. 배열 정렬
17+
3-3. 이분탐색
18+
- start, end, 를 각각 1과 arr[n-1] - arr[0]로 초기화.
19+
- 공유기를 최소거리만큼 띄워서 설치.
20+
- 설치 공유기 개수가 c보다 작으면 end를 mid로 설정.
21+
- 설치 공유기 개수가 c이상이면 start를 mid+1로 설정.
22+
- start와 end가 교차하면 종료
23+
24+
'''
25+
26+
import sys
27+
28+
inp = sys.stdin.readline
29+
30+
31+
def install_router(mid):
32+
# 가장 왼쪽의 집은 무조건 설치
33+
router_count = 1
34+
previous_house = house[0]
35+
36+
# 이전에 공유기를 설치했던 집 좌표 + mid <= 현재 집 좌표인지 확인
37+
for i in range(N):
38+
if previous_house + mid <= house[i]:
39+
router_count += 1
40+
previous_house = house[i]
41+
42+
return router_count
43+
44+
45+
# 입력받기
46+
N, C = map(int, inp().split())
47+
house = list(map(int, [inp() for _ in range(N)]))
48+
49+
# 정렬
50+
house.sort()
51+
52+
# 인접한 두 집의 가능한 최소거리와 최대거리
53+
start = 1
54+
end = house[N - 1] - house[0]
55+
56+
# 정답
57+
answer = 0
58+
59+
while start <= end:
60+
# 이분탐색을 위한 mid
61+
mid = (start + end) // 2
62+
63+
# 설치한 공유기 개수를 반환
64+
router_count = install_router(mid)
65+
66+
if router_count >= C:
67+
start = mid + 1
68+
answer = mid
69+
else:
70+
end = mid - 1
71+
72+
print(answer)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'''
2+
3+
1.하나의 옵션에 대해 왼쪽에서부터 오른쪽 순서로 단어의 첫 글자가(공백으로 구분하는 것을 이용) 이미 단축키로 지정되었는지 살펴본다.
4+
만약 단축키로 아직 지정이 안 되어있다면 그 알파벳을 단축키로 지정한다.
5+
6+
2. 만약 모든 단어의 첫 글자가 이미 지정이 되어있다면 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.
7+
8+
3.어떠한 것도 단축키로 지정할 수 없다면 그냥 놔두며 대소문자를 구분치 않는다.
9+
10+
4. 위의 규칙을 첫 번째 옵션부터 N번째 옵션까지 차례대로 적용한다.
11+
12+
'''
13+
14+
import sys
15+
16+
inp = sys.stdin.readline
17+
18+
N = int(inp())
19+
20+
# 단축키로 지정된 대문자 알파벳들
21+
used_shortcuts = set()
22+
23+
# 결과 저장용 리스트
24+
results = []
25+
26+
for _ in range(N):
27+
original = inp().strip()
28+
shortcut_index = -1
29+
words = original.split()
30+
index_in_string = 0
31+
32+
# 1단계: 각 단어의 첫 글자 확인
33+
for word in words:
34+
char = word[0].upper()
35+
if char not in used_shortcuts:
36+
used_shortcuts.add(char)
37+
shortcut_index = index_in_string
38+
break
39+
index_in_string += len(word) + 1 # 공백 포함해서 다음 인덱스 계산
40+
41+
# 2단계: 전체 문자열 순회
42+
if shortcut_index == -1:
43+
for i, char in enumerate(original):
44+
if char != ' ' and char.upper() not in used_shortcuts:
45+
used_shortcuts.add(char.upper())
46+
shortcut_index = i
47+
break
48+
49+
# 단축키 표시
50+
if shortcut_index != -1:
51+
marked = (
52+
original[:shortcut_index]
53+
+ '[' + original[shortcut_index] + ']'
54+
+ original[shortcut_index + 1:]
55+
)
56+
results.append(marked)
57+
else:
58+
results.append(original)
59+
60+
# 출력
61+
print('\n'.join(results))
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'''
2+
1. 아이디어
3+
- 방향이 두가지이고 최소거리는 둘레 // 2 보다 작거나 같아야 하므로, 시계방향 거리를 구해서 둘레 // 2와 비교하며 처리하자
4+
- 동근이와 상점의 시계방향 거리를 구할때는 (0,0)을 기준점으로 잡고 기준점부터 동근이의 거리, 기준점부터 상점의 거리를 구한 후 차이를 구하자
5+
6+
2. 시간복잡도
7+
상점 위치 입력 → O(nums)
8+
거리 계산 → O(nums)
9+
최대 O(100)로 1초안에 가능 (n이 100이하니까)
10+
11+
3. 구현
12+
3-1. 입력 받기
13+
3-2. 전체 둘레 계산
14+
3-3. 시계 방향으로 거리 계산 함수 정의
15+
3-4. (0,0)에서부터 시계방향으로 동근이와 상점의 거리 구하기
16+
3-5. 3-4를 기반으로 시계방향으로 동근이와 상점의 거리 구하기
17+
3-6. 시계방향 거리가 전체 둘레의 절반보다 작다면 시계방향을 더하고, 크다면 반시계방향 거리 더하기
18+
3-7. 결과 출력
19+
'''
20+
21+
import sys
22+
23+
inp = sys.stdin.readline
24+
25+
row, col = map(int, inp().strip().split())
26+
27+
# 전체 둘레
28+
round_length = row * 2 + col * 2
29+
answer = 0
30+
31+
# 동근이의 위치와 상점의 좌표 저장
32+
locations = []
33+
n = int(inp().strip())
34+
35+
for _ in range(n + 1):
36+
dir, num = map(int, inp().strip().split())
37+
locations.append((dir, num))
38+
39+
40+
def calculate_distance(dir, num):
41+
if dir == 1:
42+
return num
43+
elif dir == 2:
44+
return row + col + (row - num)
45+
elif dir == 3:
46+
return row + col + row + (col - num)
47+
else:
48+
return row + num
49+
50+
51+
for i in range(n):
52+
# 동근이 좌표
53+
dir, num = locations[n]
54+
55+
# 상점 좌표
56+
store_dir, store_num = locations[i]
57+
58+
# (0,0)에서부터 시계방향으로 동근이의 거리
59+
d1 = calculate_distance(dir, num)
60+
61+
# (0,0)에서부터 시계방향으로 상점의 거리
62+
d2 = calculate_distance(store_dir, store_num)
63+
64+
# 시계방향 동근이 - 상점간 거리
65+
distance = abs(d2 - d1)
66+
67+
if distance < round_length // 2:
68+
answer += distance
69+
else:
70+
answer += round_length - distance
71+
72+
print(answer)

0 commit comments

Comments
 (0)