[programmers] 프로그래머스 Level1 체육복
(파이썬 Python)
* 문제출처 : 프로그래머스 코딩 테스트 연습, 알고리즘 문제
1) 문제
코딩테스트 연습 - 체육복
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번
programmers.co.kr
2) 코드
1) 그리디 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
def solution(n, lost, reserve):
answer = n - len(lost)
remove_list = []
for lost_student in lost :
for reserve_student in reserve :
if (lost_student == reserve_student) :
remove_list.append(lost_student)
for remove_student in remove_list :
answer += 1
lost.remove(remove_student)
reserve.remove(remove_student)
for i in range(1, n + 1) :
if i in lost :
# front
front = i - 1
if (front in reserve) :
answer += 1
reserve.remove(front)
continue
# rear
rear = i + 1
if (rear in reserve) :
answer += 1
reserve.remove(rear)
return answer
|
cs |
시간복잡도 : O(30)
1-1) 완전탐색(dfs) - 파이썬 스타일 풀이(set 자료구조 이용 및 파이썬 표준 함수 max() 사용)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
def dfs(cur_idx, n, lost, reserve) :
if (cur_idx > n) :
return 0
if (cur_idx in lost) :
# borrow front
front_idx = cur_idx - 1
if (front_idx in reserve) :
reserve.remove(front_idx) # 중복 제거
front_answer = dfs(cur_idx + 1, n, lost, reserve) + 1
reserve.append(front_idx)
else :
front_answer = -1
# borrow rear
rear_idx = cur_idx + 1
if (rear_idx in reserve) :
reserve.remove(rear_idx)
rear_answer = dfs(cur_idx + 1, n, lost, reserve) + 1
reserve.append(rear_idx)
# not borrow rear
else :
rear_answer = -1
else :
front_answer = -1 # Not happened
rear_answer = -1 # Not happened
# 지금 현재 상태에서 빌리지 않았을 때 최대한의 경우
no_borrow_answer = dfs(cur_idx + 1, n, lost, reserve)
best_answer = max(front_answer, rear_answer, no_borrow_answer)
return best_answer
def solution(n, lost, reserve):
set_lost = sorted(set(lost)-set(reserve))
set_reserve = sorted(set(reserve)-set(lost))
answer = n-len(set_lost)
best_borrow_case = dfs(1, n, set_lost, set_reserve)
return answer + best_borrow_case
|
cs |
2. Low한 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
def dfs(cur_idx, n, lost, reserve) : #cur_idx 학생(잃어 버린) n번째 위치에 있을 때
앞에서 빌려 올 수도 있고, 뒤에서 빌릴 수 있다. if (cur_idx > n) : return 0
if (cur_idx in lost) :
# borrow front
front_idx = cur_idx - 1
if (front_idx in reserve) :
reserve.remove(front_idx) # 중복 제거
front_answer = dfs(cur_idx + 1, n, lost, reserve) + 1
reserve.append(front_idx)
# not borrow front
else :
front_answer = -1
# borrow rear
rear_idx = cur_idx + 1
if (rear_idx in reserve) :
reserve.remove(rear_idx)
rear_answer = dfs(cur_idx + 1, n, lost, reserve) + 1
reserve.append(rear_idx)
# not borrow rear
else :
rear_answer = -1
else :
front_answer = -1 # Not happened
rear_answer = -1 # Not happened
# 지금 현재 상태에서 빌리지 않았을 때 최대한의 경우
no_borrow_answer = dfs(cur_idx + 1, n, lost, reserve)
if (front_answer >= rear_answer) and (front_answer >= no_borrow_answer) :
best_answer = front_answer
elif (rear_answer >= front_answer) and (rear_answer >= no_borrow_answer) :
best_answer = rear_answer
else :
best_answer = no_borrow_answer
return best_answer
def solution(n, lost, reserve):
answer = n - len(lost)
#내가 있는데, 내가 도난당한 경우를 리스트로 선언한 것.
remove_list = []
# 내가 여벌이 있는데, 내가 도난당한 경우
for reserve_student in reserve :
for lost_student in lost :
if (lost_student == reserve_student) :
remove_list.append(lost_student)
# 내가 여벌이 있는데, 내가 도난을 당했으면 나 부터 써야지. 그럼 나는 잃어버린것도 아니고,
여분이 있는것도 아님. 그래서 뺀거임. for remove_student in remove_list :
answer += 1
lost.remove(remove_student)
reserve.remove(remove_student)
best_borrow_case = dfs(1, n, lost, reserve)
return answer + best_borrow_case
|
cs |
3) 풀이 과정
핵심 : 체육복을 최대한 많이 빌려야 한다.(최대한 많이 체육 수업을 듣기 위해서)
How?
1) 체육복을 도난당한 사람
2) 체육복을 여벌로 가지고 온 사람
3) 2)의 사람이 1)사람과 겹치면, 먼저 처리한다.
< < 사고 과정 > >
1. 최대한 많은 학생들이 체육 수업을 듣기 위해서는 최대한 많은 체육복이 필요하다.
2. 단순 직관적인 그리디로 생각
4) 정리 노트
X
'*Algorithm > Programmers_Level1' 카테고리의 다른 글
[programmers] 프로그래머스 Level1 소수 찾기(파이썬 Python) (0) | 2020.12.14 |
---|---|
[programmers] 프로그래머스 Level1 모의고사(파이썬 Python) (0) | 2020.11.20 |
[programmers] 프로그래머스 Level1 최대공약수와 최소공배수(파이썬 Python) (0) | 2020.10.14 |
[programmers] 프로그래머스 Level1 시저 암호(파이썬 Python) (0) | 2020.10.10 |
[programmers] 프로그래머스 Level1 이상한 문자 만들기(파이썬 Python) (0) | 2020.10.05 |
댓글