Programmers Greedyジャージ
4242 ワード
[欲張り法(Greedy)]スポーツウェア
Link: https://programmers.co.kr/learn/courses/30/lessons/42862?language=python3
問題の説明
昼食の時間に盗まれ、一部の学生の運動服が盗まれた.幸いなことに、余分な運動服を貸したい学生がいます.学生の番号は体格順で、前の番号の学生か後ろの番号の学生の運動服しか貸せません.例えば、4番の学生は3番か5番の学生にしか運動服を貸すことができません.運動服がないと授業を受けられないので、適当に運動服を借りて、できるだけ多くの学生に体育の授業をさせなければなりません.
すべての学生の数n,ジャージを盗まれた学生の番号の並びloss,複数のジャージを持った学生の番号の並びreserveをパラメータとした場合,解関数を書いて体育の授業を受けられる学生の最上位値を返してください.
<制限>
I/O例
n lost reserve return
5 [2, 4][1, 3, 5] 5
5 [2, 4][3] 4
3 [3][1] 2
Code
def solution(n, lost, reserve):
# 1. lost와 reserve에 같은 수가 있다면 제거
for x in lost:
if x in reserve:
lost.remove(x)
reserve.remove(x)
# 2
answer = n - len(lost)
# 3
while True:
temp = answer
for x in lost:
if x+1 in reserve and x-1 not in reserve:
answer += 1
reserve.remove(x+1)
lost.remove(x)
elif x-1 in reserve and x+1 not in reserve:
answer += 1
reserve.remove(x-1)
lost.remove(x)
if answer == temp: break
# 4
for x in lost:
if x-1 in reserve:
answer += 1
reserve.remove(x-1)
elif x+1 in reserve:
answer += 1
reserve.remove(x+1)
return answer
コードの説明
まず、紛失した人が余分な運動服を持っているかどうかを判断しなければならない.余計なことなら、なくしたら、あの人は自分のジャージを着ればいい.loss&reserveリストから削除します.
正解の数は、紛失した人がどれだけ着ているかを探すので、答えは「総人数-紛失した人の数」です.
私はこのドアを繰り返します.前の人にしか借りられないなら、前の人に借ります.后の人にしか借りられないなら、その人は后の人に借ります.貸し出しのたびに、スタンバイ・ユーザー・リストが更新されます.そのため、最初から見直す必要がある.これ以上借りる人がいなければ、whileドアを出ます.
今、失った人の中で、前の人や後ろの人にお金を借りることができれば、答えを増やして正解を求めます.
コードエラー
TestCase 7号にエラーがありました.明らかにアルゴリズムに問題があり、漏れがある.運動服を借りる方法の前後で一番いい方法を選ぶべきです.そうしないと、答えの数が違います.
*エラーの検出
間違いは意外に簡単だ.コード説明#1号にジャージを余す学生がいなくなった場合、貸すことができず、自分で解決しなければなりませんが、この部分ではfor loopのloss関数でlossインデックスを削除すると正解が違います.loss関数をlost copyに保存し、lost copyメソッドを使用してloss関数の項目を削除すると、問題を解決できます.
#변경사항
lost_copy = lost.copy()
for x in lost_copy:
if x in reserve:
lost.remove(x)
reserve.remove(x)
Code Output(Screenshot)
より良いコード
count = 30
def rec_(k,M,selected,lost,reserve):
temp_lost = lost.copy()
global count
if k == M:
for i in range(0,M):
#만약 0이면 앞쪽 친구가 체육복이 없는지 확인 후 빌려준다.
if selected[i]==0:
if reserve[i]-1 in temp_lost:
temp_lost.remove(reserve[i]-1)
#만약 1이면 뒷쪽 친구가 체육복이 없는지 확인 후 빌려준다.
elif selected[i]==1:
if reserve[i]+1 in temp_lost:
temp_lost.remove(reserve[i]+1)
if len(temp_lost) <= count:
count = len(temp_lost)
else:
for cand in range(0,2):
selected[k] = cand
rec_(k+1,M,selected,lost,reserve)
selected[k] = -1
def solution(n, lost, reserve):
answer = 0
global count
#여벌옷 가져온 학생이 체육복을 잃어버리는 경우
lost_copy = lost.copy()
for i in range(len(lost_copy)):
if lost_copy[i] in reserve:
lost.remove(lost_copy[i])
reserve.remove(lost_copy[i])
print(lost,reserve)
M = len(reserve)
selected = [-1 for _ in range(M)]
rec_(0,M,selected,lost,reserve)
answer = n - count
return answer
Reference
この問題について(Programmers Greedyジャージ), 我々は、より多くの情報をここで見つけました https://velog.io/@kakasi18/ProgrammersGreedy체육복テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol