본문 바로가기

연습18

[그리디] 만들 수 없는 금액 N 개의 동전을 가지고 있고, 화폐 단위는 1,000,000 이하의 자연수다. 이때 N 개의 동전을 이용하여 만들 수 없는 양의 정수 금액 중 최솟값을 구해라. 예를 들어 N = 5이고 각 동전이 3원, 2원, 1원, 1원, 9원 이라면 만들 수 없는 양의 정수 금액 중 최솟값은 8원이다. 또 다른 예로 N = 3이고 각 동전이 3원, 5원, 7원 이라면 답은 1원이다. 문제를 보고 처음든 생각은 이랬다. 가능한 모든 수를 Set으로 저장해놓고 1부터 1,000,000 까지 for문 돌려서 없는 숫자가 나오면 답인것으로. 그런데 모든 수를 구하기 위한 방식이 마땅치 않았다. 답 코드를 보면 먼저 정렬 한 후에, 구해야 되는 target 숫자를 차례차례 체크하는 방식으로 이루어져 있다. 예를 들어 data.. 2021. 10. 3.
[그리디] 문자열 뒤집기 S 문자열은 0과 1로만 이루어져 있다. S 문자열에 있는 모든 숫자를 전부 같게 만드려고 한다. S 에서 연속된 하나 이상의 숫자를 잡고 뒤집을 수 있다. 뒤집는 것은 1을 0으로, 0을 1로 바꾸는것을 의미한다. 예를 들어 S 가 00011000 일때 모두 같게 하려면, 모두 1로 만들거나 모두 0으로 만들어야 한다. 먼저 모두 1로 만든다면 전체를 뒤집으면 1110011이 되고 그 후 4,5번째 문자를 뒤집으면 1111111 이 되어서 두번만에 모두 같은 숫자로 만들 수 있다. 다음 모두 0으로 만든다면 4,5번째 문자를 뒤집으면 00000000 이 되어서 한번만에 모두 같은 숫자로 만들 수 있고 정답은 1이 된다. 이 문제를 보고 처음 고민한 내용들이다. 복기를 위해 잘못된 생각도 그대로 적었다... 2021. 9. 26.
[그리디] 모험가 길드 모험가 N 명이 있다. 모험가들은 각각의 공포도를 갖고 있다. 그래서 공포도가 X 인 모험가는 반드시 X 명 이상으로 구성한 모험가 그룹에 참여해야 여행을 떠날 수 있다. 최대 몇개의 모험가 그룹을 만들수 있는가? 예를 들어 N이 5이고 각 모험가 공포도가 2 3 1 2 2 라고 해보자. 이때 group1(1 2 3), group2(2 2) 이렇게 두개의 그룹을 만들 수 있다. 그런데 문제의 조건이 더 있다. 몇명의 모험가들은 그룹에 포함되지 않아도 된다. 다시말해 모든 모험가를 특정한 그룹에 넣을 필요는 없다. 이렇게 되면 group1(1), group2(2 2) 도 정답이 된다. 둘 다 답은 2로 같은데 group이 되는 과정이 달라서 헷갈렸다. 그리고 모험가들은 같은 공포도를 갖는다고 하더라도 개별.. 2021. 9. 23.
[그리디] 큰 수의 법칙 n 개의 다양한 수로 이뤄진 배열이 있다. 그 수들을 m 번 더해서 가장 크게 만들어야 한다. 단, 배열안의 특정 수가 k번 초과해서 더해질 수는 없다. 예를들어 n이 5인 [2,4,5,4,6] 배열로 m이 8, k가 3(8번 더하지만 특정 수가 3번 초과하면 안됌)인 상황에서 가장 큰 수를 만드려면 6+6+6+5+6+6+6+5=46 이 된다. 그리고 서로 다른 인덱스지만 숫자가 같은 경우는 서로 다른 것으로 간주한다. 예를들어 [3,4,3,4,3] 인 배열에 m이 7이고 k가 2이면 4+4+4+4+4+4+4 = 28이 된다. 결국 배열에서 필요한 숫자는 가장 큰 수와 그다음 큰수 두개 뿐이다. 그래서 먼저 배열을 정렬하는게 첫 이슈인데 책에서 정렬까지 직접 구현하진 않았고 라이브러리를 이용했다. # 큰.. 2021. 9. 13.
파이썬 기본문법 정리 # 10^9 표현을 1e9 라고 함 정수형으로 전환하기 위해 int wrap a = int(1e9) print(a) # 실수 a = 0.3 + 0.6 print(a) if a == 0.9: print(True) else: print( False) # round b = round(123.456, 2) print(b) # 123.456 에서 소수점 둘째자리 까지. 셋째에서 반올림 # 파이썬에서 나누기 연산의 결과는 기본적으로 실수형이다(자바는 몫만 나오는데) # 파이썬에서 몫을 얻기 위해 '//' 연산자를 사용한다. a = 7 b = 3 print(a/b) print(a//b) # 거듭제곱 연산자 '**' print(a**b) # 리스트 초기화. 크기가 10이고 모든값이 0인 1차원 리스트 초기화 n = 1.. 2021. 9. 6.
[그리디] 곱하기 혹은 더하기 문제 : 각 자리가 0~9 로만 이루어진 문자열이 주어졌을 때 왼쪽부터 오른쪽까지 차례대로 더하거나 곱해서 가장 큰수가 되게 만들기 사칙연산 방식과는 달리 모든 연산은 왼쪽부터 오른쪽으로 차례대로 진행된다. 예를들어 02984 문자열이 주어지면 ((((0+2)*9)*8)*4) = 576 이다. 이 문제를 풀 때 핵심은 0이나 1이 있을 때 곱하기를 안하고 더하기를 해줘야 한다는점, 그리고 for문을 돌 때 index outof bound가 발생하지 않게끔 해줘야 한다는 점이 제일 중요한거 같다. 두 수를 비교하기 위해서 index, index+1 을 비교하는 방식으로 할까 하다가 out of bound 가 날 수 있으므로, 0번째 인덱스는 미리 갖고 있고 1부터 len(data) 까지 for문을 돌게 하.. 2021. 9. 6.