본문 바로가기

문제 풀이/Baekjoon

[백준] S5 11507번 카드셋트 (JAVA)

문제 출처 - Baekjoon Online Judge

문제는 여기

 

11507번: 카드셋트

예제1 : 12 12 11 13은 잃어버린 P카드 :  12개, K : 12개, H : 11개, T : 13라는 뜻이다. 예제2 : 같은 카드(H02)가 존재하므로 GRESKA을 출력하였다.

www.acmicpc.net

[문제] 

최근에 진솔이는 로봇 공학을 하기 시작했다. 그래서 포커 카드가 완전한 세트인지 확인하는 로봇을 만들기로 결심했다.

그는 프로그램을 작성하는 일을 분담했다. 그 프로그램은 카드의 모양(스페이드(♠), 하트(♡), 다이아몬드(♢), 클럽(♣))을 인식하는 것이다. 문제를 간단하게 하기 위해서 모든 카드는 하나의 모양과 하나의 숫자를 가진다고 가정한다.

여기서 그 모양은 실제 그림 대신 문자로 대체한다. P,K,H,T에 해당한다. 그리고 숫자는 1~13에 해당하는 정수이다. 로봇은 각각의 카드를 TXY의 형태로 '카드 이름'을 정하는데 T는 모양에 해당하고 XY는 숫자에 해당한다. 만약 만약 숫자가 1자리 숫자이면 X=0에 해당한다. ex) 01.

만약에 모양이 P이고 숫자가 9이면 P09이다.

완벽한 카드 한 세트는 52개로 이루어져 있다. (4 (모양)x 13(숫자))

로봇은 모든 카드의 '카드이름'을 읽고 문자열 S로 결합한다.

이제 진솔이가 프로그래밍 하는 것을 도와주자.  문자열을 읽어 얼마나 많은 카드를 잃어버렸는지 세면 된다.

만약에 2개의 같은 카드가 존재한다면 GRESKA이라고 출력하면 된다.

[입력]

오직 1줄만 문자열 S(1 ≤ |S| ≤ 1000)가 들어온다. 이것은 현재 가지고 있는 카드 이름에 해당한다.

[출력]

만약 똑같은 카드가 존재한다면 GRESKA을 출력한다.

그렇지 않으면 4개의 정수를 공백 문자로 구분하여 출력한다. 각각 P, K, H, T에 해당한다.

 

 


[풀이]

1. 입력은 공백이 없이 한줄로 쭉 이루어져 있다. ==> 따라서, StringTokenizer로 처리는 불가능하다.

2. 입력은 알파벳숫자1숫자2...숫자2으로 된다는 규칙이 있으므로 for문으로 처리해 줄 수 있다.

3. for문으로 처리 해주며 알파벳에 따른 값과 숫자1숫자2를 합친 num에 대한 처리를 해주면 된다.

4. 이미 입력이 된 것이라면, 조건에 맞게 "GRESKA"를 입력하고 종료시킨다.

5. 입력이 되지 않은 것이라면 해당 값을 true로 변경해주고, 해당 모양의 수를 증가시켜준다.

6. 모양마다 13개씩 존재하므로 13에서 각 모양의 수를 빼주면 필요한 카드의 개수가 나오게 된다.

[접근]

1. 해시 맵을 사용해서 문제를 풀면 더욱 빨리 풀 수 있을 것이라고 생각하고 처음엔 해시 맵으로 접근하였다.

2. 하지만 해시 맵말고 배열로 문제를 해결해도 시간적으로 문제없을 것 같아서 배열로 문제를 해결하였다.

[코드]

package BOJ_silver;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main_S5_11507 {
	static String str; // 입력받은 문자열
	static char c; // 카드 모양 (char형 => 입력받을 때 사용)
	static int num; // 카드의 번호
	static int shape; // 카드의 모양
	static boolean card[][] = new boolean[4][14];
	static int cnt[] = new int[4];

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		str = br.readLine();
		
		// 한줄로 문자열이 쭉 나열되서 입력이 된다.
		// 이는 알파벳(카드모양)숫자1숫자2라는 규칙으로 나열되어있기 때문에
		// 3씩 증가시켜서 처리해준다.
		for (int i = 0; i < str.length(); i += 3) {
			// 맨 처음은 알파벳
			c = str.charAt(i);
			// 그 다음 두 자리는 숫자 1, 숫자 2
			num = (str.charAt(i + 1) - '0') * 10 + (str.charAt(i + 2) - '0');
			
			// 알파벳에 따라서 번호를 주어준다.
			// 출력을 P,K,H,T순으로 해줘야 하기 때문에
			// 이 순서대로 번호를 주었다.
			switch (c) {
			case 'P':
				shape = 0;
				break;
			case 'K':
				shape = 1;
				break;
			case 'H':
				shape = 2;
				break;
			case 'T':
				shape = 3;
				break;
			}
			
			// 카드가 이미 있는 것이라면 출력 후 바로 종료
			if (card[shape][num]) {
				System.out.println("GRESKA");
				System.exit(0);
			}
			// 카드가 없다면 입력받았으니 있다고 변경
			card[shape][num] = true;
			// 해당 모양의 개수를 증가
			cnt[shape]++;
		}
		
		// 모양에 따른 갯수는 최대 13개이다.
		// 그러므로 13 - 해당 모양의 개수를 빼주면 필요한 카드의 개수가 된다.
		for (int i = 0; i < 4; i++) {
			System.out.print(13 - cnt[i] + " ");
		}
	}
}