갬미의 성장일기
[이것이 코딩테스트다] 12일차 - 백준 연산자 끼워넣기, 인구이동 본문
본문은 [이것이 취업을 위한 코딩테스트다 - 나동빈] 책을 공부하고 작성한 글입니다.
Chapter 5 DFS/BFS
오늘 풀이한 문제
1. [백준 14888] 연산자 끼워넣기
14888번: 연산자 끼워넣기
첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수,
www.acmicpc.net
문제 설명
N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다. 우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다. 예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.
|
접근 방법 (permutations 라이브러리 사용)
1. 각 연산자 개수만큼 연산자가 모두 담긴 리스트를 만들고 itertools의 permutations를 이용하여 가능한 모든 연산자 조합을 만든다
oper_list = []
for p in range (plus): oper_list.append('+')
for m in range (minus): oper_list.append('-')
for mu in range (mul): oper_list.append('*')
for d in range (div): oper_list.append('//')
oper_list ## 2 1 1 1 -> ['+', '+', '-', '*', '//']
2. 연산자 리스트를 돌며 숫자를 순서대로 불러와 연산 후 결과 저장
3. min, max출력
n= 6
## 연산자 조합 만들기
plus, minus, mul, div = map(int, input().split())
nums = 1,2,3,4,5,6
oper_list = []
for p in range (plus): oper_list.append('+')
for m in range (minus): oper_list.append('-')
for mu in range (mul): oper_list.append('*')
for d in range (div): oper_list.append('//')
from itertools import permutations
per_oper = list(permutations(oper_list, len(oper_list)))
result = []
for oper in per_oper:
num = nums[0]
for idx,o in enumerate (oper):
if o == '+':
num += nums[idx+1]
elif o =='-':
num -= nums[idx+1]
elif o =='*':
num *= nums[idx+1]
else:
if num < 0:
num = ((num*(-1)) // nums[idx+1])*(-1)
else:
num = num // nums[idx+1]
result.append(num)
print (max(result), min(result))
접근 방법 (DFS)
## dfs
n= 6
plus, minus, mul, div = map(int, input().split())
nums = 1,2,3,4,5,6
max_ans, min_ans = -1e9, 1e9
def solution(num, idx, add, sub, mul, div):
global max_ans, min_ans
if idx == n:
max_ans = max(max_ans, num)
min_ans = min(min_ans, num)
return
## 각 연산을 할때 마다 숫자를 차감하는 방식
if add > 0:
solution(num + nums[idx], idx + 1, add - 1, sub, mul, div)
if sub > 0:
solution(num - nums[idx], idx + 1, add, sub - 1, mul, div)
if mul > 0:
solution(num * nums[idx], idx + 1, add, sub , mul -1, div)
if div > 0:
solution(int(num / nums[idx]), idx + 1, add, sub, mul, div -1)
solution(nums[0], 1, plus, minus, mul, div)
print(max_ans)
print(min_ans)
엄청 어려운 문제는 아니었지만 dfs로 풀 경우 속도가 훨씬 빠르다고 하니 재귀로 푸는 경우도 많이 연습해야겠다!
2. [백준 16234] 인구 이동
문제 설명
N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다. 오늘부터 인구 이동이 시작되는 날이다. 인구 이동은 하루 동안 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다.
|
접근 방법 (BFS)
0. 방문을 확인 할 country과 동일한 크기의 check 리스트, 유닛별 평균 인구수를 구하고 기존 country에 업데이트 하기 위한 pin 변수 준비
1. dx, dy 를 사용하여 이동할 좌표를 구하고 다음 좌표가 한번도 방문하지 않고, 인구 차이가 l~r 사이라면 이동
방문한 좌표의 check = 1, pin에 좌표 저장
2. 이동할 수 있는 위치가 없으면 평균 인구를 구해 country 업데이트
from collections import deque
def bfs(x,y):
q = deque()
q.append((x,y))
check[x][y] = 1 ## 방문확인
pin = [(x,y)] ## 좌표저장
people = country[x][y] ## 시작하는 곳의 인구수
while q:
x,y = q.popleft()
for f in range (4):
nx = x + dx[f]
ny = y + dy[f]
if nx < 0 or nx>= n or ny < 0 or ny >= n:
continue
if check [nx][ny] == 1: ## 방문한 곳 패스
continue
p = abs(country[x][y] - country[nx][ny])
if l <= p <= r: ## 방문한적 없고, 인구 차이가 조건 이내일 때
people += country[nx][ny]
check[nx][ny] = 1
q.append((nx,ny))
pin.append((nx,ny))
p_new = people // len(pin)
for p_x, p_y in pin: ## 새로운 인구수 업데이트
country[p_x][p_y] = p_new
return len(pin)
country =[[10,15,20], [20,30,25], [40,22,10]]
n = 3
l, r = 5, 10
cnt= 0
dx = [0,0,1,-1]
dy = [1,-1,0,0]
while True :
stop = True
check = [[0]*n for _ in range(n)]
for i in range (n):
for j in range(n):
if check[i][j] == 0 :
if bfs (i,j) > 1:
stop = False
if stop :
break
else:
cnt += 1
print (cnt)
bfs를 여러번 수행하는 곳에서 살짝 어려움이 있었다 그래도 많이 수월해졌다 아자자~
연습문제 풀이는 깃허브에도 업로드 되어있습니다
GitHub - gymin97/algorithm_study: Solve the algorithm problems (python3)
Solve the algorithm problems (python3). Contribute to gymin97/algorithm_study development by creating an account on GitHub.
github.com
'Algorithm > Algorithm Study' 카테고리의 다른 글
[이것이 코딩테스트다] 13일차 - 정렬 예제풀이 (0) | 2021.12.15 |
---|---|
[이것이 코딩테스트다] 13일차 - 정렬 (0) | 2021.12.15 |
[이것이 코딩테스트다] 11일차 - 프로그래머스 괄호변환 (0) | 2021.12.12 |
[이것이 코딩테스트다] 10일차 - 백준 경쟁적 전염 (0) | 2021.12.11 |
[이것이 코딩테스트다] 9일차 - 백준 연구소 (0) | 2021.12.09 |