[Java] 백준 1620번 [나는야 포켓몬 마스터 이다솜] 자바

백준 1620번
https://www.acmicpc.net/problem/1620


문제

...생략

오박사 : 그럼 다솜아 이제 진정한 포켓몬 마스터가 되기 위해 도감을 완성시키도록 하여라. 일단 네가 현재 가지고 있는 포켓몬 도감에서 포켓몬의 이름을 보면 포켓몬의 번호를 말하거나, 포켓몬의 번호를 보면 포켓몬의 이름을 말하는 연습을 하도록 하여라. 나의 시험을 통과하면, 내가 새로 만든 도감을 주도록 하겠네.


입력

첫째 줄에는 도감에 수록되어 있는 포켓몬의 개수 N이랑 내가 맞춰야 하는 문제의 개수 M이 주어져. N과 M은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수인데, 자연수가 뭔지는 알지? 모르면 물어봐도 괜찮아. 나는 언제든지 질문에 답해줄 준비가 되어있어.

둘째 줄부터 N개의 줄에 포켓몬의 번호가 1번인 포켓몬부터 N번에 해당하는 포켓몬까지 한 줄에 하나씩 입력으로 들어와. 포켓몬의 이름은 모두 영어로만 이루어져있고, 또, 음... 첫 글자만 대문자이고, 나머지 문자는 소문자로만 이루어져 있어. 아참! 일부 포켓몬은 마지막 문자만 대문자일 수도 있어. 포켓몬 이름의 최대 길이는 20, 최소 길이는 2야. 그 다음 줄부터 총 M개의 줄에 내가 맞춰야하는 문제가 입력으로 들어와. 문제가 알파벳으로만 들어오면 포켓몬 번호를 말해야 하고, 숫자로만 들어오면, 포켓몬 번호에 해당하는 문자를 출력해야해. 입력으로 들어오는 숫자는 반드시 1보다 크거나 같고, N보다 작거나 같고, 입력으로 들어오는 문자는 반드시 도감에 있는 포켓몬의 이름만 주어져


출력

첫째 줄부터 차례대로 M개의 줄에 각각의 문제에 대한 답을 말해줬으면 좋겠어!!!. 입력으로 숫자가 들어왔다면 그 숫자에 해당하는 포켓몬의 이름을, 문자가 들어왔으면 그 포켓몬의 이름에 해당하는 번호를 출력하면 돼


예제 입력

26 5
Bulbasaur
Ivysaur
Venusaur
Charmander
Charmeleon
Charizard
Squirtle
Wartortle
Blastoise
Caterpie
Metapod
Butterfree
Weedle
Kakuna
Beedrill
Pidgey
Pidgeotto
Pidgeot
Rattata
Raticate
Spearow
Fearow
Ekans
Arbok
Pikachu
Raichu
25
Raichu
3
Pidgey
Kakuna

예제 출력

Pikachu
26
Venusaur
16
14

생각하기

처음 구상한 코드는 Iterator의 EntrySet을 통해서 출력을 하려고 했습니다.

			Iterator<Entry<String, Integer>> it = map.entrySet().iterator();
			
			while(it.hasNext()) {
				Entry<String, Integer> entrySet = (Entry<String, Integer>)it.next();   

정답은 당연히 잘 나오는데, 문제는 시간초과였습니다.
시간초과는 아무리 고민해도 방법이 안나와서 다른 분들의 코드를 참고해서 풀었습니다.

참고 1
참고 2


동작

이번 문제에서는 동작은 제가 설명할 부분은 적다고 참고하여 공부하고 알게 된 점 위주로 적어보려고 합니다.

제출 결과를 보시면 알겠지만, 시간은 조금 줄어들다가 마지막에 조금 커졌지만, 메모리는 지속적으로 줄어들었다는 것을 알 수 있습니다.

제가 평소 사용하던 코드와 달랐던 점은 첫 번째가 stoi를 사용한 점 입니다.

		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = stoi(st.nextToken()); // 포켓몬의 개수
		int M = stoi(st.nextToken()); // 문제의 개수

평소에는 항상 Integer.paseInt()를 사용해서 문자열 변경을 했는데, 다른 분은 stoi를 사용해서 메소드로 실행을 시켜주었습니다.

물론 stoi 메소드를 직접 만들기는 했지만, 이 과정때문에 당연히 시간이나 메모리가 증가할거라고 생각했는데, 오히려 시간이 줄고 메모리도 줄어들어드는 모습을 확인할 수 있었습니다.

두 번째는 아스키코드 입니다.

저 같은 경우 이 문제에서 포켓몬의 번호인 num을 Integer.toString()을 사용해서 문자열로 변경한 반면, 다른 분은 아스키 코드의 0 ~ 9의 번호인 48 ~ 57을 사용하셨더라구요.

물론 여기서는 57 이하라고만 표시해줬습니다. 그 이유는 48이하는 특수문자이기때문에, 굳이 이상은 표시해주지 않아도 되기 때문입니다.

아스키 코드 참고

아스키코드를 직접 사용하고 나서 메모리와 시간이 줄어든 모습을 확인했습니다.

앞으로 해당 문제와 비슷한 유형이 있을 경우, 자주 사용하며 효율적인 코드를 짤 수 있도록 노력해야 할 것 같습니다.


TMI


진짜 똑똑하신 분들 많다 respect




코드

import java.io.*;
import java.util.*;

public class Main {

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = stoi(st.nextToken()); // 포켓몬의 개수
		int M = stoi(st.nextToken()); // 문제의 개수

		String arr[] = new String[N + 1];
		HashMap<String, Integer> map = new HashMap<>();

		for(int i=1; i<=N; i++) {
			String pokemon = br.readLine();
			arr[i] = pokemon;
			map.put(pokemon, i);
		}

		while(M --> 0) {
			String Q = br.readLine();

			if(Q.charAt(0) <= 57) {
				int key = Integer.parseInt(Q);
				sb.append(arr[key]+"\n");
			}
			else {
				sb.append(map.get(Q)+"\n");
			}

		}

		System.out.println(sb);

	} // End of main

	private static int stoi(String nextToken) {
		return Integer.parseInt(nextToken);
	}
} // End of class

좋은 웹페이지 즐겨찾기