알고리즘 문제풀이/Greedy 27

(파이썬 python) 백준 13904번 : 과제(greedy)

점수가 큰 과제를 뒤에서부터 채워나가는 방법으로 과제를 해결하도록 계획을 세워야 한다. (처음엔 점수가 큰 과제부터 한다거나 마감일이 빠른 과제부터 끝내는 방법을 생각해보았지만 답은 아니었다.) 마감일 | 점수 4 | 60 4 | 40 1 | 20 2 | 50 3 | 30 4 | 10 6 | 5 이렇게 과제와 마감일이 주어져있을 때 가장 점수가 높은 과제부터 마감일부터 뒤로 계획을 세워준다. 60점 과제는 4일째 50점 과제는 2일째 40점 과제는 4일째에 이미 60점짜리를 해야하므로 3일째 30점 과제는 3일째, 2일째 이미 다른 과제가 있으므로 1일째 20점,10점 과제는 남은 기간이 없으므로 패스 5점 과제는 6일째 이런 식으로 이런 알고리즘을 구현하는 데엔 heap 자료구조를 사용하는 것이 유용하..

(파이썬 python) 백준 1213번 : 팰린드롬 만들기(greedy)

구글링에서 본 것중 가장 직관적이고 쉬운 풀이를 가져왔다. names = input() name_cnt = [0 for _ in range(26)] for name in names: name_cnt[ord(name)-65] += 1 odd = 0 odd_alpha = '' alpha = '' for i in range(26): if name_cnt[i] % 2 == 1: odd += 1 odd_alpha += chr(i+65) alpha += chr(i+65) * (name_cnt[i] // 2) if odd > 1: print("I'm Sorry Hansoo") else: print(alpha+odd_alpha+alpha[::-1]) # 참고 : https://alpyrithm.tistory.com/1..

(파이썬 python) 백준 11000번 : 강의실 배정(greedy)

우선 입력할 때 input으로 하니 시간초과가 떳다. -> sys라이브러리의 stdin.readline사용. 로직 1. 강의시간을 시작시간으로 정렬. 2. 맨 처음 강의시간의 종료시간과 두번째 강의의 시작시간을 비교 - 시작시간보다 종료시간이 느리면 새로운 강의실 배정 -> room에 heapq.heappush로 추가. - 시작시간보다 종료시간이 빠르면 기존 강의실의 종료시간 수정 -> room에 heapq.heappop 으로 기존 강의실 종료시 간을 제거하고 heapq.heappush로 새로운 종료시간 추가 굳이 heap자료구조를 사용해야 하나 생각을 해보았다. 우선 heap 자료구조가 시간복잡도 측면에서 list보다 효율적이고 heap을 사용하면 최소힙을 계속 유지해주기도 한다. # 11000번: 강..

(파이썬 python) 백준 9237번 : 이장님 초대(greedy)

1. 다 자라는데 가장 오랜 기간이 걸리는 나무를 첫 날 심어줘야 하기 때문에 나무를 내림차순 정렬 2. 심는데 1일, 다 자라고 나서 1일 총 2일 필요 + 심는 날짜 별로 일수 추가 3. 제일 늦게 완성되는 날짜 일수 출력. 예 - [2,3,4,3]의 나무가 있는 경우 1. 나무 [4,3,3,2]로 정렬 2. 각 나무 완성에 필요한 일수 계산 -> [2,3,4,5]를 각각 자리별로 더해줌. 3. 더해진 리스트에서 최대값 출력 # 9237번 : 이장님 초대 n = int(input()) li = list(map(int,input().split())) li.sort(reverse=True) li2 = [i+2 for i in range(n)] ans = [x+y for x,y in zip(li,li2)]..

백준 1343번 : 폴리오미노 (greedy)

1. 먼저 '.' 을 기준으로 입력값을 구분할 수 있도록 split함수를 사용하였다. 2. 구분된 리스트의 각 값들의 길이가 홀수이면 -1을 출력할 수 있도록 해준다. 이 때, flag변수를 설정해서 구분하였다. 3. 먼저 'AAAA'를 4로 나눈 몫만큼 곱해주고 나머지에 2로 나눈 몫만큼 'BB'에 곱해준다. 사실 지금 생각해보니 2로 나눈 몫은 항상 1이 될 수 밖에 없다. (결과는 같다.) 참고 print함수를 사용해서 list를 차례대로 출력하려고 할 때 *를 리스트 앞에 붙여주면 띄어쓰지 않고 출력해준다. 이 때 sep, end같은 print내부 옵션도 당연히 사용 가능하다. # 1343번 : 폴리오미노 li = input().split('.') ans = [] flag = 0 for i in ..

백준 1138번: 한 줄로 서기(greedy)

입력값만큼 키가 큰 사람을 앞에 두고 줄을 세우는 문제이다. 왼쪽부터 숫자 0의 개수를 기준으로 위치를 찾아 줄을 세우면 된다. 예를 들어 2,1,1,0 이면 [0,0,1,0] -> 0을 2개 지나친 이후 1 위치 [0,2,1,0] -> 0을 1개 지나친 이후 2 위치 [0,2,1,3] -> 0을 1개 지나친 이후 3 위치 [4,2,1,3] -> 0을 0개 지나친 이후 4 위치 # 1138번 : 한 줄로 서기 n = int(input()) li = list(map(int,input().split())) ans = [ 0 for i in range(n)] for i in range(n): cnt = 0 for j in range(n): if cnt == li[i] and ans[j] == 0: ans[j]..

백준 3109번: 빵집 - 파이썬(greedy)

DFS알고리즘을 알고 있어야 풀 수 있는 문제다. R,C로 행과 열의 값 pipe에 파이프라인 visited에 파이프가 이미 설치되어 있는 곳인지 확인하기 위해 False로 초기화 리스트 이런 변수들을 입력 및 선언하고 왼쪽부터 시작해서 맨 오른쪽이 원웅이네 가게 파이프라인까지 최대한 많은 선을 연결해야 하므로 첫번째 열 에서 파이프라인이 있는 지점 pipe[i][0] == '.' 에서 부터 탐색을 시작한다. solve함수를 호출하여 건물이 있는 지점을 피하며 오른쪽으로 이동하고, 방문했던 지점은 True로 흔적을 남긴다. solve함수 종료조건인 j == C - 1 까지 도착하게 되면 True를 반환하여 cnt를 증가시킨다. # 3109번 : 빵집 def solve(i,j): # 원웅이네 파이프로 무사..

백준 2847번: 게임을 만든 동준이 - 파이썬(greedy)

가장 높은 레벨이 가장 큰 점수를 얻어야 하는 문제인데 최소한의 횟수를 사용해야 하므로 점수 조정시 다음 레벨과의 점수 차이를 1로 만들어 주면 된다. 문제를 풀 때 주의해야 할 점은 높은 레벨에서부터 비교하면서 점수를 낮춰주어야 한다. 낮은 레벨부터 점수를 낮추게 되면 [5,5,5] > [4,5,5] > [4,4,5] 이런 식으로 점수가 오름차순이 되지 않을 수 있다. 실제로 처음에 이렇게 풀었다가 틀렸었다... # 2847번 : 게임을 만든 동준이 n = int(input()) levels = [] for _ in range(n): levels.append(int(input())) levels.reverse() cnt = 0 for i in range(n-1): while levels[i]

백준 1449번: 수리공 항승 - 파이썬(greedy)

문제를 풀기위해 생각해낸 방법은 "테이프로 막은 부분을 표시해두자" 이다. 표시를 하기 위해서 사용한 방법은 리스트를 넉넉한 크기로 만들어준 뒤 테이프로 막은 부분은 1로 표시하는 것이다. 그래서 변수 명도 flag 로 정했다. (항상 변수명을 정할 때 가장 고민을 많이 하는 것 같다...ㅎㅎ) # 1449번: 수리공 항승 N,L = map(int,input().split()) tape = list(map(int,input().split())) tape.sort() flag = [0 for i in range(10000)] cnt = 0 for i in tape: if flag[i] == 0: cnt += 1 for j in range(L): flag[i+j] = 1 print(cnt)

백준 1543번: 문서 검색 - 파이썬(greedy)

# 1543번: 문서 검색 doc = input() word = input() length = len(word) flag = [0 for i in range(len(doc))] cnt = 0 for i in range(len(doc)): if flag[i] == 1: continue if word == doc[i:i+length]: cnt += 1 for idx in range(i,i+length): flag[idx] = 1 print(cnt) 중복 값을 어떻게 처리하면 좋을지 생각하다가 리스트를 사용해서 한번 본 문자의 인덱스에 표시를 해두는 것으로 구현해보았다. 다행히 한 번에 통과가 되었다. 그런데 이번 문제를 풀면서 새롭게 알게 된 부분은 리스트 슬라이스 작업에는 index out of range..