새소식

PS/백준

[백준/20529] 가장 가까운 세 사람의 심리적 거리 (Python)

  • -

Problem : https://www.acmicpc.net/problem/20529

 

20529번: 가장 가까운 세 사람의 심리적 거리

각 테스트 케이스에 대한 답을 정수 형태로 한 줄에 하나씩 출력한다.

www.acmicpc.net

 

Difficulty : Silver 1

 

Status : Solved

 

Time : 00:12:00

 


 

문제 설명

 

더보기

 

여러분은 요즘 유행하는 심리검사인 MBTI에 대해 들어보았는가?

MBTI(Myers-Briggs Type Indicator)는 C.G.Jung의 심리유형론을 근거로 하여 Katharine Cook Briggs와 Isabel Briggs Myers가 보다 쉽고 일상생활에 유용하게 활용할 수 있도록 고안한 자기보고식 성격유형지표이다. (출처: 위키백과)

MBTI는 아래와 같이 네 가지 척도로 사람들의 성격을 구분한다.

* 외향(E) / 내향(I)
* 감각(S) / 직관(N)
* 사고(T) / 감정(F)
* 판단(J) / 인식(P)

 

각 척도마다 두 가지 분류가 존재하므로, MBTI는 총 2^4 = 16가지 유형이 있음을 알 수 있다. 일반적으로 MBTI의 유형들은 각 분류를 나타내는 알파벳 한 글자씩을 따 네 글자로 표시하게 된다. 모든 유형의 목록은 다음과 같다.

ISTJ, ISFJ, INFJ, INTJ, ISTP, ISFP, INFP, INTP, ESTP, ESFP, ENFP, ENTP, ESTJ, ESFJ, ENFJ, ENTJ


MBTI 성격 유형을 이용하면 두 사람 사이의 심리적인 거리를 정의할 수 있다. 이는 두 사람의 MBTI 유형에서 서로 다른 분류에 속하는 척도의 수로 정의된다. 예를 들어, MBTI 유형이 ISTJ인 사람과 ISFJ인 사람 사이의 거리는 1이며, INTP인 사람과 ENTJ인 사람 사이의 거리는 2이다.

이 정의를 확장해서 세 사람 사이의 심리적인 거리도 정의할 수 있다. 세 사람 A, B, C가 있을 때 이들의 심리적인 거리는

(A와 B 사이의 심리적인 거리) + (B와 C 사이의 심리적인 거리) + (A와 C 사이의 심리적인 거리)

로 정의한다.

대학교에서 심리학 교수로 일하는 종서는 자신이 가르치는 학생들의 심리적인 특성을 분석하고 싶어한다.

오늘이 생일인 종서를 위해 N명의 학생들의 MBTI 유형이 주어질 때, 가장 가까운 세 학생 사이의 심리적인 거리를 구해보자.

 

 

입력 및 출력

 

더보기

입력

 

첫 줄에는 테스트 케이스의 수를 나타내는 정수 T가 주어진다.

각 테스트 케이스의 첫 줄에는 학생의 수를 나타내는 하나의 정수 N이 주어지며, 두 번째 줄에는 각 학생의 MBTI 성격 유형을 나타내는 문자열들이 사이에 공백을 두고 주어진다.

 

출력

 

각 테스트 케이스에 대한 답을 정수 형태로 한 줄에 하나씩 출력한다.

 

입력 예시

 

3
3
ENTJ INTP ESFJ
4
ESFP ESFP ESFP ESFP
5
INFP INFP ESTP ESTJ ISTJ

 

출력 예시

 

8
0
4

 

 


 

풀이

 

기본적인 접근법은 브루트포스가 딱 적당할 것 같으나, 최대 N의 개수는 무시무시하게도 100000에 육박한다. 브루트포스로 도전하려면 O(N^3)의 시간복잡도가 요구되므로, 브루트포스는 정답이 아닐 것만 같다....

 

하지만 다행히도, MBTI 성향 개수는 16개밖에 되지 않는다. 그리고 당연히도, 같은 MBTI를 가진 사람들의 심리적 거리는 0이다. 따라서 비둘기집의 원리에 의해, 최악의 경우에도 33명 이상의 사람이 존재하게 되면 같은 MBTI를 가진 사람의 수가 3명이 넘게 된다. 즉 이 경우에는 세 사람의 심리적 거리가 최소치인 0이 되므로, N >= 33인 케이스에 대해서는 연산할 필요가 없다.

 

풀이 코드

import sys
input = sys.stdin.readline

def dist(a, b, c) :
  result = 0
  for i in range(4) :
    if a[i] != b[i] :
      result += 1
    if b[i] != c[i] :
      result += 1
    if c[i] != a[i] :
      result += 1
  return result

T = int(input())
for _ in range(T) :
  N = int(input())
  mbti = input().split()
  if N > 32 :
    print(0)
    continue
  answer = float('inf')
  for i in range(N-2) :
    for j in range(i+1, N-1) :
      for k in range(j+1, N) :
        tmp = dist(mbti[i], mbti[j], mbti[k])
        if tmp < answer :
          answer = tmp
  print(answer)

풀이 완료!

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.