본문 바로가기

문제 노트/백준

Cowpatibility( BOJ 16764 )

문제

16764. Cowpatibility : https://www.acmicpc.net/problem/16764

 

16764번: Cowpatibility

Here, cow 4 is not compatible with any of cows 1, 2, or 3, and cows 1 and 3 are also not compatible.

www.acmicpc.net

 

문제 파악하기

  • 친구가 될 수 없는 소들의 쌍을 찾는 문제입니다.
  • 아이스크림의 맛은 총 5개 입력되며, 단순히 중첩 반복문을 사용하기에는 N의 값이 너무 큽니다.
  • 단순히 아이스크림 맛을 카운트하기에는 중복되는 소들을 계산할 수 없습니다.
  • 이 문제는 map 자료형을 사용해야 합니다.

 

문제 해결하기 #1

  • map은 탐색에 필요한 키값해당 키값에 할당된 내용값으로 구성됩니다.
  • 각 소마다 5가지의 맛을 좋아하므로 나올 수 있는 맛의 부분 집합 수는 총 31가지(공집합X) 입니다.
  • 그렇다면 31가지 경우를 map에 저장한 다음, 각 경우의 수에 해당하는 소의 개수를 카운트하면 되지 않을까요?
  • 예를 들어 1번 소는 {1, 2, 3, 4, 5}를 좋아하고 2번 소는 {2, 3, 4, 10, 6}을 좋아한다고 가정해봅시다.
    그렇다면 1번 소와 친구가 될 수 있는 경우의 수는 {1}, {2}, ... , {1, 2, 3, 4, 5}까지 총 31가지가 됩니다.
    또한 2번 소와 친구가 될 수 있는 경우의 수는 {2}, {3}, ... , {2, 3, 4, 10, 6}까지 총 31가지 있습니다.
    여기서 1번 소와 2번 소가 친구가 될 수 있는 경우의 수는 중복을 제외하면 1가지가 나오게 됩니다.
  • 이렇듯 map에는 vector형을 이용한 부분집합을 키값으로 하고, 해당 경웨 해당하는 소의 개수를 내용값으로 할당합니다.
  • 그 후, 각각의 부분집합에 대해 포함된 소의 개수포함-배제 기법을 통해 카운트하면 문제를 풀 수 있습니다.

 

문제 해결하기 #2

  • bitset이라는 자료구조를 사용하는 방법도 있습니다.
  • bitset은 원하는 크기의 비트값을 저장할 수 있는 자료형입니다.
  • 각각의 맛을 어떤 소가 좋아하는지 비트값으로 저장하면 손쉽게 겹치는 소의 마리수를 파악할 수 있습니다.
  • 예시)  map< int, bitset<50000> > m;
  • 위와 같이 map을 선언하면 해당 맛을 좋아하는지 여부에 따라 1 또는 0의 비트열을 저장합니다.
  • 이후에는 각각의 소가 좋아하는 맛을 입력받을 때마다 OR연산을 진행하면 됩니다.
    5가지 맛을 모두 입력받았으면 m.count()를 이용해 1의 개수(소의 마리수)를 카운트하면 됩니다.
  • 마지막으로 지금까지 카운트된 소의 마리수를 전체 경우의 수( n*(n-1)/2 )에서 빼주면 문제는 해결됩니다.

 

후기

map을 떠올리지 못해 고생했던 문제입니다. 개인적으로 bitset을 이용한 풀이법이 간편했는데 공식 솔루션을 확인해보니 포함_배제를 염두한 문제였다는게 새로웠습니다.

'문제 노트 > 백준' 카테고리의 다른 글

굉장한 학생( BOJ 2336 )  (0) 2021.03.13
Fine Dining( BOJ 16763 )  (0) 2020.12.13
사탕 가게( BOJ 4781 )  (0) 2020.11.29
터보소트( BOJ 3006 )  (0) 2020.11.23
숫자 게임( BOJ 2923 )  (0) 2020.11.19