728x90
문제
* 주어진 N개의 MBTI 유형 중, 임의로 3가지를 골라,
* A와 B의 다른 글자 수 + B와 C의 다른 글자 수 + C와 A의 다른 글자 수를 구해서 가장 작은 수를 출력
문제 링크 : https://www.acmicpc.net/problem/20529
원리
1. OUTER 문법을 사용한 반복문 : continue OUTER나 break OUTER를 이용해 각 테스트 케이스 내 N중 반복문 컨트롤
continue OUTER : OUTER가 있는 최외각 반복문의 반복으로 이어서 진행
break OUTER : OUTER 반복문을 종료
2. 이너 클래스를 이용한 객체 생성시, 주어진 파라미터의 값에 따라 서로 다른 값의 필드를 가진 객체 생성
private static class Student {
private int M,B,T,I;
public Student (String mbti) {
M = mbti.contains("E") ? 0 : 1;
B = mbti.contains("N") ? 0 : 1;
T = mbti.contains("F") ? 0 : 1;
I = mbti.contains("P") ? 0 : 1;
}
}
3. 각 조건에 따른 계산을 static 메소드에 위임하고, 결과값을 이용한 값 비교
1. main 메소드에서 min값을 비교해서 min값 업데이트
min = Math.min(min, sumDist(list.get(first),list.get(second),list.get(third)));
2. 추출한 3명의 조합을 이용한 결과값을 얻기위한 메소드이며,
조합 내에서 또 다시 2명씩 뽑아내 계산하는 것은 static 메소드에 위임
private static int sumDist (Student fst, Student snd, Student thd) {
return (distance(fst, snd) + distance(snd,thd) + distance(fst, thd));
}
3. 두 값의 차이를 계산해서 반환해주는 메소드
private static int distance(Student student1, Student student2) {
int sum = 0;
if(student1.M != student2.M) sum++;
if(student1.B != student2.B) sum++;
if(student1.T != student2.T) sum++;
if(student1.I != student2.I) sum++;
return sum;
}
4. 이 문제는 3개의 값만 추출한다는 조건이 있으므로, 3중 반복으로 조합을 구하며,
원래는 모든 조합을 비교한 후 min값을 반환하지만, 최소값의 한계인 0이되는 값이 나오면 즉시 종료.
for ( int first=0 ; first<list.size(); first++ ) {
for ( int second=first+1 ; second<list.size() ; second++ ) {
for( int third = second+1 ; third<list.size() ; third++ ) {
// 기존 조합의 최소값과 현재 새로 계산한 조합의 합산 중 더 작은 값을 메모라이즈
min = Math.min(min, sumDist(list.get(first),list.get(second),list.get(third)));
// 반복 중, 만약에 최소값이 0, 즉 세명의 MBTI가 모두 같은 경우가 발생하면, 나올 수 있는 최솟값이 더이상없으므로,
// 현재 반복 종료 후 다음케이스로 이동
if (min==0) {
bw.write(""+min+"\n");
continue OUTER;
}
}
}
}
bw.write(""+min+"\n");
나의 코드
: 이번엔 레퍼런스 코드 방식이 새로워서 해당 작성 방식에 대한 이해를 중점적으로 진행했다.
: 특히 OUTER를 사용한 반복문 사용 방식, 조건문을 활용한 객체의 특성 부여 방식 등이 있었다.
import java.util.*;
import java.io.*;
public class no20529 {
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int N, min; // 각 케이스별 학생의 수
StringTokenizer st; // 각 케이스별 MBTI들
int T = Integer.parseInt(br.readLine());
// OUTER 문법 : OUTER로 지정한 반복문에 대한 Break, countnue를 호출하면, 그 안의 다른 반복문에 전부 적용됨.(개꿀)
OUTER : for (int test = 0 ; test<T ; test++ ) {
N = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine(), " ");
min = Integer.MAX_VALUE;
List<Student> list = new ArrayList<>();
for(int i=0 ; i<N ; i++) list.add(new Student(st.nextToken()));
/**
* N명 중 3명을 뽑는 경우의 수이므로, 3중 반복문으로 해결 가능하다.
* (반복의 횟수가 지정되어 있기에 가능한 방식)
*/
for ( int first=0 ; first<list.size(); first++ ) {
for ( int second=first+1 ; second<list.size() ; second++ ) {
for( int third = second+1 ; third<list.size() ; third++ ) {
// 기존 조합의 최소값과 현재 새로 계산한 조합의 합산 중 더 작은 값을 메모라이즈
min = Math.min(min, sumDist(list.get(first),list.get(second),list.get(third)));
// 반복 중, 만약에 최소값이 0, 즉 세명의 MBTI가 모두 같은 경우가 발생하면, 나올 수 있는 최솟값이 더이상없으므로,
// 현재 반복 종료 후 다음케이스로 이동
if (min==0) {
bw.write(""+min+"\n");
continue OUTER;
}
}
}
}
bw.write(""+min+"\n"); // 모든 경우의 수를 확인 하고 나온 최솟값을 이번 케이스의 출력에 저장
}
bw.close();
}
/**
* 두 학생 사이의 거리계산 메소드를 3번 호출하여, 총 거리를 반환함
* @param fst = A학생
* @param snd = B학생
* @param thd = C학생
* @return 세 학생끼리의 각각의 거리 합
*/
private static int sumDist (Student fst, Student snd, Student thd) {
return (distance(fst, snd) + distance(snd,thd) + distance(fst, thd));
}
/**
* 두 학생 사이의 거리 계산
*/
private static int distance(Student student1, Student student2) {
int sum = 0;
if(student1.M != student2.M) sum++;
if(student1.B != student2.B) sum++;
if(student1.T != student2.T) sum++;
if(student1.I != student2.I) sum++;
return sum;
}
/**
* 각 학생 객체
* : 생성 조건을 들어온 MBTI마다 ENFP를 기준으로 T/F
*/
private static class Student {
private int M,B,T,I;
public Student (String mbti) {
M = mbti.contains("E") ? 0 : 1;
B = mbti.contains("N") ? 0 : 1;
T = mbti.contains("F") ? 0 : 1;
I = mbti.contains("P") ? 0 : 1;
}
}
}
레퍼런스
참고 링크 : jsleeg98님의 벨로그
레퍼런스 코드
더보기
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
OUTER : for (int tc = 0; tc < T; tc++) {
int N = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
ArrayList<Person> pList = new ArrayList<Person>();
for (int i = 0; i < N; i++) {
pList.add(new Person(st.nextToken()));
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < pList.size(); i++) {
for (int j = i+1; j < pList.size(); j++) {
for (int k = j+1; k < pList.size(); k++) {
min = Math.min(min, sumDistance(pList.get(i), pList.get(j), pList.get(k)));
if(min == 0) {
System.out.println(min);
continue OUTER;
}
}
}
}
System.out.println(min);
}
}
private static int sumDistance(Person person1, Person person2, Person person3) {
int sum = 0;
sum += distance(person1, person2);
sum += distance(person2, person3);
sum += distance(person1, person3);
return sum;
}
private static int distance(Person person1, Person person2) {
int sum = 0;
if(person1.M != person2.M)
sum++;
if(person1.B != person2.B)
sum++;
if(person1.T != person2.T)
sum++;
if(person1.I != person2.I)
sum++;
return sum;
}
static class Person{
int M;
int B;
int T;
int I;
public Person(String mbti) {
if(mbti.contains("E"))
M = 0;
else
M = 1;
if(mbti.contains("S"))
B = 0;
else
B = 1;
if(mbti.contains("T"))
T = 0;
else
T = 1;
if(mbti.contains("J"))
I = 0;
else
I = 1;
}
}
}
728x90
'알고리즘 저장소 (일반방식과 나만의 풀이) > JAVA' 카테고리의 다른 글
| [백준] no1238: 파티 - 다익스트라 (0) | 2023.06.12 |
|---|---|
| [백준] no1167: 트리의 지름 - 단방향 탐색 DFS (0) | 2023.06.09 |
| [백준] no21736: 헌내기는 친구가 필요해 - BFS 지도탐색 (0) | 2023.06.07 |
| [백준] no14940: 쉬운 최단거리 (0) | 2023.06.06 |
| [백준] no11444: 피보나치 수 6 - 수학(행렬) (0) | 2023.06.05 |