728x90
반응형
SW Expert Academy에서 학습용으로 문제를 가져왔습니다. 문제가 될 시 수정, 삭제하겠습니다.
https://swexpertacademy.com/main/main.do
문제 : 1부터 12까지의 숫자를 원소로 가진 집합 A가 있다. 집합 A의 부분 집합 중 N개의 원소를 갖고 있고, 원소의 합이 K인 부분집합의 개수를 출력하는 프로그램을 작성하시오.
해당하는 부분집합이 없는 경우 0을 출력한다. 모든 부분 집합을 만들어 답을 찾아도 된다.
예를 들어 N = 3, K = 6 경우, 부분집합은 { 1, 2, 3 } 경우 1가지가 존재한다.
[입력]
첫 줄에 테스트 케이스 개수 T가 주어진다. ( 1 ≤ T ≤ 50 )
테스트 케이스 별로 부분집합 원소의 수 N과 부분 집합의 합 K가 여백을 두고 주어진다. ( 1 ≤ N ≤ 12, 1 ≤ K ≤ 100 )
[출력]
각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다.
input
3
3 6
5 15
5 10
output
#1 1
#2 1
#3 0
code
numbers=[_ for _ in range(1,13)] #1부터 12까지 숫자의 리스트를 만들어준다.
lst=[] #빈 리스트 생성
for i in range(1 << len(numbers)): #비트연산자로 1*2^len(numbers)
sub_lst=[] #빈 부분집합 리스트
for j in range(len(numbers)):
if i & (1<<j):
sub_lst.append(numbers[j])
lst.append(sub_lst) #부분집합을 만들어 빈 리스트에 부분집합을 넣어준다.
Test_case=int(input())
for t in range(1,Test_case+1):
N,K=map(int,input().split())
count=0
for s in lst:
if len(s) == N and sum(s) ==K: #리스트의 길이는 N, 리스트의 합은 K
count+=1
print('#{} {}'.format(t, count))
문제의 흐름을 정리해봅시다.
1.문제에서 요구한대로 1부터 12까지의 숫자 리스트를 형성해줍니다.
2.비트연산중 shift연산자를 사용하였습니다.
ex)
1 << 0 이면 1 (이진수)
1 << 1 이면 10 (이진수)
1 << 2 이면 100 (이진수)
1 << 4 10000 이고 2^4인 16이다.
즉 numbers = [1,2,3,4,5,6,7,8,9,10,11,12] 이므로 총 1<< 12 == 1000000000000(이진수) == 2^12 ==5048 만큼 돈다는 것입니다.
3.빈 부분집합 리스트를 만드는데 if i & (1 << j) 이 구문이 생소할 수 있습니다. 간단히 설명하자면
&는 AND를 찾는 비트연산자로, 예를 들어 A & B에서 A와 B의 2진수 형태에서 공통된 값을 10진수로 변환해 리턴해주는 역할을 합니다.
예시)
print(5 & 4)
=>4
위의 예시는 4를 리턴해줍니다. 5의 2진수 형태는 101이고, 4의 2진수 형태는 100입니다. 그러므로 5와 4의 교집합은 100이기 때문에 이것을 10진수로 변환해 4를 출력합니다.
즉 i와 2의 j승이 지정된 범위안에서 교집합이면 부분집합 리스트에 넣어줍니다. 그 후 부분집합리스트를 만들어준 리스트(lst)에 넣어줍니다.
이 리스트(lst)를 가지고 만약 리스트의 길이가 N이고 리스트의 합이 K이면 count에 1을 더해줍니다.
간단한 code
import itertools
Test_case = int(input())
numbers = [i for i in range(1,13)]
for t in range(1,Test_case+1):
N,K = map(int,input().split())
combi = list(itertools.combinations(numbers,N))
count = 0
for i in combi:
if sum(i)==K:
count+=1
print('#{} {}'.format(t, count))
itertools함수를 사용하여 더 간단하게 pass할 수 있습니다.
itertools의 combinations을 이용하여 1부터 12까지의 리스트에서 N개를 뽑아 합이 0이면 count에 1을 더해주므로서 부분집합의 수를 구할 수 있습니다.
반응형
'Programming > SWEA' 카테고리의 다른 글
[SWEA 4843].[파이썬 S/W 문제해결 기본] 2일차 - 특별한 정렬 (0) | 2021.08.02 |
---|---|
[SWEA 4839].[파이썬 S/W 문제해결 기본] 2일차 - 이진탐색 (0) | 2021.08.02 |
[SWEA 4836].[파이썬 S/W 문제해결 기본] 2일차 - 색칠하기 (0) | 2021.08.01 |
[SWEA 4835].[파이썬 S/W 문제해결 기본] 1일차 - 구간합 (1) | 2021.07.31 |
[SWEA 4834].[파이썬 S/W 문제해결 기본] 1일차 - 숫자 카드 (0) | 2021.07.31 |