[JAVA] 백준 1764. 듣보잡

이 글은 읽는데 약 3분이 걸립니다.

※개인 공부 목적의 정리글입니다.
이 글의 내용이 최선의 해답은 아닐 수 있습니다.

문제

김진영이 듣도 못한 사람의 명단과, 보도 못한 사람의 명단이 주어질 때, 듣도 보도 못한 사람의 명단을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다. 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다. 이름은 띄어쓰기 없이 알파벳 소문자로만 이루어지며, 그 길이는 20 이하이다. N, M은 500,000 이하의 자연수이다.

듣도 못한 사람의 명단에는 중복되는 이름이 없으며, 보도 못한 사람의 명단도 마찬가지이다.

출력

듣보잡의 수와 그 명단을 사전순으로 출력한다.

요약

듣도 못한 사람과 보도 못한 사람을 따로 Set로 받은다음, 두 Set을 교집합 연산하면 쉽게 구할 수 있다.
듣도 보도 못한 사람은 두 집합에 공통으로 포함되기 때문이다.

코드

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();

String[] s = br.readLine().split(" ");
int N = Integer.parseInt(s[0]);
int M = Integer.parseInt(s[1]);

HashSet<String> noListen = new HashSet<>();
HashSet<String> noSee = new HashSet<>();

for(int i=0; i<N; i++){
    noListen.add(br.readLine());
}
for(int i=0; i<M; i++){
    noSee.add(br.readLine());
}

noListen.retainAll(noSee);

ArrayList<String> arr = new ArrayList<>(noListen);
Collections.sort(arr);

sb.append(arr.size());
sb.append("\n");
for(String name : arr){
    sb.append(name);
    sb.append("\n");
}

System.out.println(sb.toString());
br.close();

여기서는 HashSet을 사용했다. 먼저 N과 M을 입력 받은 후, N만큼 줄을 읽어서 듣도 못한 사람의 명단을 집합A에 추가하고, M만큼 줄을 읽어서 보도 못한 사람의 명단을 집합 B에 추가한다.

이후 noListen집합에 retainAll 메소드로 noSee집합과의 교집합을 구한다. 교집합의 결과는 noListen 집합에 들어간다.
즉, 교집합을 구한 후에 noListen 집합은 듣도 못한 사람의 명단이 아니라, 듣보잡의 명단이 된다.

이제 듣보잡 집합을 ArrayList로 변환한다. 왜? 문제에서 출력시 사전순으로 정렬해야 한다고 하였기 때문이다.
ArratList로 변환되면 정렬을 해주고 듣보잡의 수와 이름을 출력해주면 끝!

여담

개인적으로 문제가 재미있었다. 1620 나는야 포켓몬 마스터 이다솜 문제도 그렇고 백준을 풀다보면 은근 재미있는 문제가 많이 있다.

댓글