일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- LCA
- union find
- 분할정복
- 내란수괴
- 윤석열
- DP
- 유니온 파인드
- 알고리즘
- BFS
- dfs 백트래킹
- 비상계엄
- 다익스트라
- 구조론
- 재귀함수
- 백준
- 이분 탐색
- 윤석열 내란수괴
- 왈왈왈
- 내란죄
- 오블완
- 프림
- 파비우스 전략
- 티스토리챌린지
- 민주주의
- 내란수괴 윤석열
- ccw
- 투 포인터
- Python
- Prim
- dfs
- Today
- Total
Toolofv 님의 블로그
[Python] 백준 2629 - 양팔저울 본문
백준 - 2629 양팔 저울
첫째 줄에는 추의 개수가 자연수로 주어진다. 추의 개수는 30 이하이다. 둘째 줄에는 추의 무게들이 자연수로 가벼운 것부터 차례로 주어진다. 같은 무게의 추가 여러 개 있을 수도 있다. 추의 무게는 500g이하이며, 입력되는 무게들 사이에는 빈칸이 하나씩 있다.
www.acmicpc.net
문제
양팔 저울과 몇 개의 추가 주어졌을 때, 이를 이용하여 입력으로 주어진 구슬의 무게를 확인할 수 있는지를 결정하려고 한다.
무게가 각각 1g과 4g인 두 개의 추가 있을 경우, 주어진 구슬과 1g 추 하나를 양팔 저울의 양쪽에 각각 올려놓아 수평을 이루면 구슬의 무게는 1g이다. 또 다른 구슬이 4g인지를 확인하려면 1g 추 대신 4g 추를 올려놓으면 된다.
구슬이 3g인 경우 아래 <그림 1>과 같이 구슬과 추를 올려놓으면 양팔 저울이 수평을 이루게 된다. 따라서 각각 1g과 4g인 추가 하나씩 있을 경우 주어진 구슬이 3g인지도 확인해 볼 수 있다.

<그림 2>와 같은 방법을 사용하면 구슬이 5g인지도 확인할 수 있다. 구슬이 2g이면 주어진 추를 가지고는 확인할 수 없다.
추들의 무게와 확인할 구슬들의 무게가 입력되었을 때, 주어진 추만을 사용하여 구슬의 무게를 확인 할 수 있는지를 결정하는 프로그램을 작성하시오.

입력
첫째 줄에는 추의 개수가 자연수로 주어진다. 추의 개수는 30 이하이다. 둘째 줄에는 추의 무게들이 자연수로 가벼운 것부터 차례로 주어진다. 같은 무게의 추가 여러 개 있을 수도 있다. 추의 무게는 500g이하이며, 입력되는 무게들 사이에는 빈칸이 하나씩 있다. 세 번째 줄에는 무게를 확인하고자 하는 구슬들의 개수가 주어진다. 확인할 구슬의 개수는 7이하이다. 네 번째 줄에는 확인하고자 하는 구슬들의 무게가 자연수로 주어지며, 입력되는 무게들 사이에는 빈 칸이 하나씩 있다. 확인하고자 하는 구슬의 무게는 40,000보다 작거나 같은 자연수이다.
출력
주어진 각 구슬의 무게에 대하여 확인이 가능하면 Y, 아니면 N 을 차례로 출력한다. 출력은 한 개의 줄로 이루어지며, 각 구슬에 대한 답 사이에는 빈칸을 하나씩 둔다.
문제 해결 방법 - (서칭으로 참고후 해결)
1. 갖고 있는 추 리스트대로 dp를 구성한다. (행 인덱스는 '추의 갯수', 열 인덱스는 '잴 수 있는 구슬의 무게'이다.) 재귀함수에 주어진 추를 올려서 리턴하고 있는데 다음 추도 계속 올려야 할지 모르므로 1차원 DP로는 짜기가 어렵다. 어떤 분기에서 dp에 이미 무게가 등록되어 있을 경우 다음 추를 올려서 얻을 수 있는 무게가 반영되지 않는다.
2. l (왼쪽 저울), r (오른쪽 저울)을 만들고, 주어진 추의 배열대로 idx를 증가시키며 1) 각각 안 올릴 때, 2) l 에 올릴 때, 3) r 에 올릴 때의 분기를 가진 재귀함수를 만든다. abs( l - r )의 값은 결국 '잴 수 있는 구슬의 무게'다.
-> 결과적이긴 하지만 abs( l - r ) 의 값이 '구슬의 무게' 일 때 잴 수 있다는 거다.
1) 주어진 확인하고자 하는 구슬의 무게가 dp에 있으면 잴 수 있는 것이다.
3. 브루트포스 시 $O(3^{n})$의 시간복잡도를 가진다고 한다. dp로 먼저 계산된 값들은 제외시켜서 시간상 효율을 버는 것.
import sys
input = sys.stdin.readline
n = int(input())
d = list(map(int, input().split()))
m = int(input())
c = list(map(int, input().split()))
dp = [[0 for _ in range(15001)] for _ in range(n)]
ans = []
def sol(idx, l, r):
t = abs(l-r) # 잴 수 있는 구슬의 무게, 구슬의 처음무게는 이 함수에 올려놓지 않았다.
if t not in ans: # t의 값은 잴 수 있는 구슬의 무게다.
ans.append(t)
if idx == n:
return 0
if dp[idx][t] != 0: # 이미 dp에 기록된 잴 수 있는 구슬의 무게였다면 제외하는 것.
return
dp[idx][t] = 1
sol(idx+1, l, r)
sol(idx+1, l+d[idx], r)
sol(idx+1, l, r+d[idx])
sol(0, 0, 0)
for i in c:
if i in ans:
print('Y')
else:
print('N')
'Algorithm' 카테고리의 다른 글
[Python] 백준 - 1260 DFS와 BFS (2) | 2024.06.11 |
---|---|
[Python] 백준 - 3015 오아시스 재결합 (1) | 2024.06.07 |
[Python] 백준 11049 - 행렬 곱셈 순서 (0) | 2024.06.05 |
[Python] 백준 2293 - 동전 1 (1) | 2024.06.05 |
[Python] 백준 1520 - 내리막길 (0) | 2024.06.05 |