[Python] 백준 23259 Celebrity

2021. 10. 31. 20:41·CS/알고리즘 & 문제풀이

문제 링크 : https://www.acmicpc.net/problem/23259

 

23259번: Celebrity

첫째 줄에 아름다운 별의 수를 출력한다.

www.acmicpc.net

1. 접근 방법

그래프의 동형 확인은 매우 어려운 작업이다.

그나마 그래프의 동형을 판별하는 몇 가지 방법을 기준으로 하나하나 분류하려 시도했는데, 너무 많은 조건을 고려해야 할 것 같아서 그래프의 조건을 기준으로 동형을 판별하는 것은 포기하고, 브루트 포스로 탐색했다.

점이 5개로 고정이므로, 각 간선 번호를 0~9번으로 하여 각 별의 상태를 비트연산으로 계산한 숫자로 처리했다.

 

 

2. 풀이 코드

🖥python 코드

from itertools import permutations
import sys
input = sys.stdin.readline


def star_to_num(star: list) -> int:
    star_now = 0
    for a, b in star:
        if a > b:
            a, b = b, a
        star_now |= 1 << pair_to_num(a, b)
    return star_now


def pair_to_num(a: int, b: int) -> int:
    # 두 점 쌍 a, b로 지정할 수 있는 숫자로 변경
    # a, b 값에 따라 지정 0 ~ 9
    if a == 0:
        return b - 1
    elif a == 1:
        return b + 2
    elif a == 2:
        return b + 4
    elif a == 3:
        return b + 5


n = int(input())
check = [0] * 1024
perms = list(permutations(range(5), 5))
for _ in range(n):
    m = int(input())
    star = []
    for _ in range(m):
        a, b = map(int, input().split())
        star.append((a - 1, b - 1))
    star_num = star_to_num(star)
    if check[star_num] == 2:
        continue
    # star의 쌍을 회전하면서 다른 대응 가능 숫자 확인
    unique = True
    similar_star_nums = []
    # 점 교환 가능한 모든 위치 확인
    for perm in perms:
        similar_star = []
        # 점 회전
        for a, b in star:
            similar_star.append((perm[a], perm[b]))
        similar_star_num = star_to_num(similar_star)
        if check[similar_star_num]:
            unique = False
        similar_star_nums.append(similar_star_num)
    # 지금 점이 유일한지
    if unique:
        check[star_num] = 1
    else:
        for similar_star_num in similar_star_nums:
            check[similar_star_num] = 2

beautiful_stars_count = check.count(1)

print(beautiful_stars_count)

📕코드 해설

각 점을 순서대로 다음을 확인한다.

1. 지금 별에 대응시킬 수 있는 숫자가 얼마인지 (비트연산)

    1.1. 만약 그 숫자를 사용할 수 있다면 추가 탐색

    1.2. 그 숫자를 사용할 수 없다면, 다음 별로 넘어가기

2. 해당 별에 대한 숫자를 사용할 수 있으면, 해당 별과 동형인 모든 그래프 탐색

 

- 별에 해당하는 숫자 찾기

가능한 간선은 총 10가지이고, 0과 1일 때 0으로, 4와 5일 때 9로 대응시켰다.

이후, 각 별의 구성에서 간선 번호를 기준으로 비트 연산으로 대응하는 별을 계산했다.

 

- 다른 동형인 별 탐색

5개의 숫자를 5개의 숫자로 치환하는 방법은 5! =120가지이고, 이를 미리 계산해두었다.

각각의 동형인 별을 탐색하고, 모든 동형을 다시 확인하면서, 동형인 별 중 불가능한 게 있다면 모두 2로, 겹치지 않는다면 처음 확인한 별만 1로 저장한다.

 

 

3. 생각 정리

그래프 이론에서 비트 연산까지 정말로 다양한 지식을 활용해 풀었다.

푸는 과정에는 정말 힘들지만, 다양한 이론을 같이 사용할 수 있는 것을 알게 되는 측면에서 절말 재밌고, 도움 되는 문제였던 것 같다.

'CS > 알고리즘 & 문제풀이' 카테고리의 다른 글

[Python] 백준 20166 문자열 지옥에 빠진 호석  (0) 2021.11.01
[Python] 백준 1186 직사각형 색칠하기  (0) 2021.11.01
[Python] 백준 23257 비트코인은 신이고 나는 무적이다  (0) 2021.10.30
[Python] 백준 22234 가희와 은행  (0) 2021.10.28
[Python] 백준 16888 루트 게임  (0) 2021.10.28
'CS/알고리즘 & 문제풀이' 카테고리의 다른 글
  • [Python] 백준 20166 문자열 지옥에 빠진 호석
  • [Python] 백준 1186 직사각형 색칠하기
  • [Python] 백준 23257 비트코인은 신이고 나는 무적이다
  • [Python] 백준 22234 가희와 은행
mintropy
mintropy
민트로피의 하루하루 오늘보다 더 나은 내일
  • mintropy
    민트로피의 민트초코
    mintropy
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 생각 정리
        • 코딩테스트
        • SSAFY
      • 디지털 노트
        • Obsidian.md
        • Notion
      • CS
        • 알고리즘 & 문제풀이
        • AI
        • DB
        • 디자인패턴
      • Projects
      • Python
        • Python Web Framework
      • JavaScript
        • React.js
      • Docker
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    구현
    DP
    SSAFY
    DRF
    fastapi
    카카오
    알고리즘
    코딩테스트
    line
    pydantic
    회고
    조건분기
    dfs
    Python
    bfs
    ps
    django
    그리디
    프로젝트
    프로그래머스
    project_zero
    백준
    게임이론
    브루트포스
    web framework
    markdown
    파이썬
    trie
    union-find
    Combinatorics
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
mintropy
[Python] 백준 23259 Celebrity
상단으로

티스토리툴바