문제 출처 : https://www.acmicpc.net/problem/20529
언어 : Kotlin
문제 설명 :
여러분은 요즘 유행하는 심리검사인 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 성격 유형을 나타내는 문자열들이 사이에 공백을 두고 주어진다.
출력 :
각 테스트 케이스에 대한 답을 정수 형태로 한 줄에 하나씩 출력한다.
제한 사항 :
- 시간 제한 : 2초
- 메모리 제한 : 1536MB
- 1 <= T <= 50
- 3 <= N <= 100,000
- 각 테스트 케이스의 N의 합은 100,000을 넘지 않는다.
입출력 예 :
입력 | 출력 |
3 3 ENTJ INTP ESFJ 4 ESFP ESFP ESFP ESFP 5 INFP INFP ESTP ESTJ ISTJ |
8 0 4 |
- 첫 번째 테스트 케이스의 경우, ENTJ와 INTP의 심리적인 거리는 2, ENTJ와 ESFJ의 심리적인 거리는 2, INTP와 ESFJ의 심리적인 거리는 4이므로 세 사람의 심리적인 거리는 2+2+4=8이다.
- 두 번째 테스트 케이스의 경우, 어떤 사람 둘을 골라도 심리적인 거리가 0이므로 가장 가까운 세 사람의 심리적인 거리는 0이다.
- 세 번째 테스트 케이스의 경우, 심리적인 거리를 최소화하려면 MBTI가 ESTP, ESTJ, ISTJ인 세 사람을 골라야 한다. ESTP와 ESTJ의 심리적인 거리는 1, ESTP와 ISTJ의 심리적인 거리는 2, ESTJ와 ISTJ의 심리적인 거리는 1이므로 세 사람의 심리적인 거리는 1+2+1=4이다.
풀이 :
세 사람을 뽑는다고 했으니 조합을 사용한다.
MBTI 유형은 총 16가지. MBTI 유형이 같은 사람이 3명이 있다면 그 거리는 무조건 0이다.
그렇다면 MBTI 유형은 32보단 작아야한다.
32보다 크게되면 무조건 같은 MBTI 유형을 가진 사람이 3명은 생겨서 답은 0이 된다.
거리를 계산하는 부분은 다음과 같다.
3명을 문제에서 말한대로 계산하는데, Set에 집어넣는다.
그럼
A의 것 4개 + B의 것 4개
B의 것 4개 + C의 것 4개
A의 것 4개 + C의 것 4개
다 더해봤을 때, 겹치는 부분이 각각 하나씩 생긴다. 4 * 3 = 12를 그래서 마지막에 빼준다.
어차피 Set으로 합치며 아예 같아서 Set의 크기가 4이거나, 아예 달라서 Set의 크기가 8이거나.
Set은 4 ~ 8의 크기를 갖게 된다.
4는 거리가 0인 것이고, 4를 넘는 것들은 거리가 있는 것이다.
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import kotlin.math.min
var distanceList = mutableListOf<String>()
fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
val bw = BufferedWriter(OutputStreamWriter(System.out))
repeat(readLine().toInt()) {
distanceList.clear()
val num = readLine().toInt()
val students = readLine().split(" ")
var result = Float.POSITIVE_INFINITY
if (students.size > 32) {
bw.appendLine("0")
} else {
combination(0, 3, 0, students, mutableListOf())
val group = distanceList.chunked(3)
for (case in group) {
val sum = (case[0] + case[1]).toSet().size + (case[1] + case[2]).toSet().size + (case[0] + case[2]).toSet().size - 12
result = min(result, sum.toFloat())
}
bw.appendLine("${result.toInt()}")
}
bw.flush()
}
bw.close()
}
fun combination(cur: Int, depth: Int, startAt: Int, list: List<String>, temp: MutableList<String>) {
if (cur == depth) {
distanceList += temp
} else {
for (i in startAt until list.size) {
temp.add(list[i])
combination(cur + 1, depth, i + 1, list, temp)
temp.removeAt(temp.lastIndex)
}
}
}
'백준 > 문제' 카테고리의 다른 글
1431번: 시리얼 번호 (0) | 2024.05.10 |
---|---|
1253번: 좋다 (0) | 2024.05.10 |
11403번: 경로 찾기 (0) | 2024.05.09 |
6064번: 카잉 달력 (0) | 2024.05.09 |
1036번: 36진수 (0) | 2024.05.08 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!