[Java] 백준(실버-4) 1620번 - 나는야 포켓몬 마스터 이다솜



문제 풀이
이번 문제는 입력받은 포켓문 문자열과 포켓몬 번호가 쌍으로 존재해야 한다.
여기선 HashMap을 활용하면 포켓몬 이름과 번호를 쉽게 쌍으로 연결지어 만들 수 있다.
아이디어 도출
- 시간제한은 2초, N의 범위는 최대 10만개, M의 범위도 최대 10만개로 이중 for문을 사용할 경우 시간제한이 발생할 가능성이 높다.
- N개의 포켓몬 문자열을 입력받으며 포켓몬 이름 문자열과 해당 인덱스를 번호로 하여 HashMap에 저장한다.
- M개의 입력받은 포켓몬 문자열이 포켓몬 이름(문자열)인지 번호(인덱스)인지 확인한다.
- 만약 문자열이라면, 이름이기에 번호를 출력한다.(HashMap의 key에 대응하는 value 값)
- 만약 번호라면, 번호이기에 이름을 출력한다.(이름을 인덱스 순으로 가지고 있는 String 배열의 인덱스에 대응하는 문자열 값)
그렇다면 아이디어대로 코드를 작성해보자.
1
2
3
4
5
6
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
HashMap<String, Integer> hm = new HashMap<>();
String[] arr = new String[N+1];
먼저 N과 M을 입력받고 포켓몬이름, 포켓몬번호를 쌍으로 담을 HashMap과 포켓몬이름을 인덱스 순으로 저장할 String 배열을 하나 생성하자.
String 배열을 별도로 만드는 이유는?
HashMap에서는 key값에 대응하는 value 값을 찾을 수 있는 get() 메서드가 있지만 key()을 찾으려면 keySet(), entrySet() 등 반복문을 한 번 돌려야지만 찾을 수 있기 때문에 String 배열에 인덱스 순으로 이름을 저장해두고 있다면 HashMap을 순회하며 key값을 찾을 필요없이 배열의 인덱스로 접근하여 가져오면 되기 때문이다.
1
2
3
4
5
for(int i=1; i<=N; i++) {
String poketmon = br.readLine();
hm.put(poketmon, i);
arr[i] = poketmon;
}
다음으로 N개의 포켓몬 이름을 입력받으며 HashMap에 key를 포켓몬 이름(문자열)으로, value를 포켓몬 번호(int형 인덱스)로 저장한다.
그리고 인덱스 순으로 이름을 arr 배열에 함께 저장한다.
1
2
3
4
5
for(int i=0; i<M; i++) {
String s = br.readLine();
if(hm.containsKey(s)) bw.write(hm.get(s) + "\n");
else bw.write(arr[Integer.parseInt(s)] + "\n");
}
마지막으로 M개의 문자열을 입력받으며 먼저 입력값이 포켓몬 이름인지 포켓몬 번호인지를 구분한다.
- 만약 포켓몬 이름이라면, 포켓몬 번호를 출력하면 된다.
- 만약 포켓몬 번호라면, 해당 번호가 인덱스이기에 위에서 포켓몬 이름을 인덱스 순으로 저장해둔 arr 배열에 인덱스로 주어 접근하면 인덱스에 해당하는 포켓몬 이름값을 가져올 수 있다.
작성코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
HashMap<String, Integer> hm = new HashMap<>();
String[] arr = new String[N+1];
for(int i=1; i<=N; i++) {
String poketmon = br.readLine();
hm.put(poketmon, i);
arr[i] = poketmon;
}
for(int i=0; i<M; i++) {
String s = br.readLine();
if(hm.containsKey(s)) bw.write(hm.get(s) + "\n");
else bw.write(arr[Integer.parseInt(s)] + "\n");
}
bw.flush();
bw.close();
br.close();
}
}
회고
- HashMap에서 value값을 get() 메서드로 찾는 것은 쉽지만 key값을 추가적인 반복문 없이 대응되는 문자열 배열만을 활용하여 찾을 수 있었다.