백준 문제풀이

1620. 나는야 포켓몬 마스터 이다솜

뮤츠 2022. 10. 3. 02:04

...문제 도입부가 포켓몬스터 프롤로그를 갖다 박았습니다. 너무 길어서 생략합니다.

 

재밌는 발상이긴한데, 조금 부담스러워요. 알고리즘에 머리싸매다 기분전환하고 싶었다고 이해합시다...

포켓몬 갓IP긴 하죠.

 

아무튼간에, 문제는 간단합니다. 문자열을 보고 (도감)번호를 캐치해서 출력하거나, (도감)번호를 보고 대응되는 문자열을 캐치하여 출력해야합니다. 보자마자 이전에 보았던 HashMap 자료형이 떠오르긴 했습니다...만, 문제는 제가 아직 key값을 추출하는 법을 몰랐습니다. 그러면 key를 통해 value는 추출할 수 있지만, value로 key값을 추출하는건 못하겠는데? 찾아봐도 뭔가 좀 어려웠어요.

 

그래서 하는수없이, 포기하고 원래 하던 고전적인 방식으로 풀었더니, 역시나 이클립스에서는 출력되나 백준에서는 시간초과가 떴습니다. 그러다가 구글링을 해보고 딱! 깨달음이 왔습니다. 숫자(순번)을 통한 호출은 배열로 하고, 문자열을 통한 숫자의 호출은 HashMap 자료형으로, Key값을 String(포켓몬이름)으로, Value값을 int(도감번호)로 하는 방식이었죠. 보통 key값은 고유값으로 뭔가 숫자여야한다는 고정관념에 사로잡혀있었습니다. 그도 그럴것이, 아직까지 HashMap 자료형을 사용한게 딱 한 번 이었고, 그게 클론코딩에 가까웠기 때문이었습니다.

 

첫번째 시도. HashMap 없이 풀다가 시간초과.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {
	
	static ArrayList<String> poke;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		
		poke = new ArrayList<>();
		
		for (int i=0; i<n; i++) {
		
			poke.add(br.readLine());
			
		}
		
		StringBuilder sb = new StringBuilder();
		
		for (int i=0; i<m; i++) {
			sb.append(find(br.readLine()) + "\n");
		}
		
		System.out.println(sb);
	}
	
	static boolean isInt(String str) {
		try {
			Integer.parseInt(str);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}
	
	static String find(String poke2) {
		
		if (isInt(poke2)) {
			return poke.get(Integer.parseInt(poke2)-1);
		} else {
			return String.valueOf(poke.indexOf(poke2)+1);
		}		
	}
}

 

두번쨰 시도. HashMap 자료형과 (약간의 검색으로) 성공.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main {
	
	static HashMap<String, Integer> poke;
	static String[] poke2;
	
	// 포켓몬 도감은 매소드와 메인이 전부 공유하는 글로벌 변수를 위해 Static 변수로 설정
	// HashMap 자료형은 이름으로 도감번호를 호출, 배열은 도감번호로 이름을 호출.
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken()); // 초기 도감 목록수
		int m = Integer.parseInt(st.nextToken()); // 맞춰야하는 입력수
				
		poke = new HashMap<>();
		poke2 = new String[n];
		
		for (int i=0; i<n; i++) {
			
			String name = br.readLine();
			poke.put(name, i);
			poke2[i] = name;
			
		} // 각 자료별로 입력값을 받아온다.
		
		StringBuilder sb = new StringBuilder();
		
		for (int i=0; i<m; i++) {
			sb.append(find(br.readLine()) + "\n");
		}
		
		System.out.println(sb);
		
	}
	
	static boolean isInt(String str) {
		try {
			Integer.parseInt(str);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}
	
	static String find(String str) {
		
		if (isInt(str)) {
			return poke2[Integer.parseInt(str)-1];
		} else {
			return String.valueOf(poke.get(str)+1);
		}		
	}
}

 

아울러, 팀 프로젝트가 다가오는 만큼, 주석다는 연습을 충실히 하려고 합니다. 제 블로그에서 문제풀이를 보시는 분들에게도, 더 도움이 될거라 생각하구요.