백준

[백준_2621번] 카드게임

빙수빈수 2021. 7. 27. 16:25

https://www.acmicpc.net/problem/2621

 

2621번: 카드게임

근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다.

www.acmicpc.net

[문제]

 근우는 오늘 재미있는 카드 게임을 배우고 있다. 카드는 빨간색, 파란색, 노란색, 녹색의 네 가지 색이 있고, 색깔별로 1부터 9까지 숫자가 쓰여진 카드가 9장씩 있다. 카드는 모두 36(=4x9)장이다. 근우가 배운 카드 게임은 36장의 카드에서 5장을 뽑고, 아래와 같은 규칙으로 정수를 계산하는 것이다.

각 카드는 다음과 같이 나타낸다. 카드의 색깔은 영어 대문자 R, B, Y, G로 나타내는데, R은 빨간색, B는 파란색, Y는 노란색, G는 녹색을 뜻한다. 예를 들어서 Y8은 노란색 8을 나타내고, B5는 파란색 5를 나타낸다.

 

<점수를 정하는 규칙>

  1. 카드 5장이 모두 같은 색이면서 숫자가 연속적일 때, 점수는 가장 높은 숫자에 900을 더한다. 예를 들어, 카드가 Y4, Y3, Y2, Y5, Y6 일 때 점수는 906(=6+900)점이다.
  2. 카드 5장 중 4장의 숫자가 같을 때 점수는 같은 숫자에 800을 더한다. 예를 들어, 카드가 B3, R3, B7, Y3, G3 일 때 점수는 803(=3+800)점이다.
  3. 카드 5장 중 3장의 숫자가 같고 나머지 2장도 숫자가 같을 때 점수는 3장이 같은 숫자에 10을 곱하고 2장이 같은 숫자를 더한 다음 700을 더한다. 예를 들어, 카드가 R5, Y5, G7, B5, Y7 일 때 점수는 757(=5x10+7+700)점이다.
  4. 5장의 카드 색깔이 모두 같을 때 점수는 가장 높은 숫자에 600을 더한다. 예를 들어, 카드가 Y3, Y4, Y8, Y6, Y7 일 때 점수는 608(=8+600)점이다.
  5. 카드 5장의 숫자가 연속적일 때 점수는 가장 높은 숫자에 500을 더한다. 예를 들어 R7, R8, G9, Y6, B5 일 때 점수는 509(=9+500)점이다.
  6. 카드 5장 중 3장의 숫자가 같을 때 점수는 같은 숫자에 400을 더한다. 예를 들어 R7, Y7, R2, G7, R5 일 때 점수는 407(=7+400)점이다.
  7. 카드 5장 중 2장의 숫자가 같고 또 다른 2장의 숫자가 같을 때 점수는 같은 숫자 중 큰 숫자에 10을 곱하고 같은 숫자 중 작은 숫자를 더한 다음 300을 더한다. 예를 들어, R5, Y5, Y4, G9, B4 일 때 점수는 354(=5X10+4+300)점이다.
  8. 카드 5장 중 2장의 숫자가 같을 때 점수는 같은 숫자에 200을 더한다. 예를 들어, R5, Y2, B5, B3, G4 일 때 점수는 205(=5+200)점이다.
  9. 위의 어떤 경우에도 해당하지 않을 때 점수는 가장 큰 숫자에 100을 더한다. 예를 들어, R1, R2, B4, B8, Y5 일 때 점수는 108(=8+100)점이다.

 입력으로 카드 5장이 주어질 때, 카드 게임의 점수를 구하는 프로그램을 작성하시오. 두 가지 이상의 규칙을 적용할 수 있는 경우에는 가장 높은 점수가 카드 게임의 점수이다.

 

[입력 조건]

 첫째 줄부터 다섯째 줄까지 한 줄에 카드 하나씩 입력된다. 카드의 색깔과 숫자 사이에는 빈 칸이 하나 있다.

 

[코드]

import java.util.*;

public class BaekJoon_2621 {
	static int[] number=new int[10]; // 1~9까지 나온 수의 빈도를 저장하는 배열
	static int[] cardvalue=new int[5]; // 입력받은 수 저장 배열
	static int[] color=new int[5]; // R,B,G,Y
	static boolean continuous=true; // 숫자가 연속적인지 판단
	static boolean fivecolor=false; // 카드 5장이 모두 같은 색인지 판단
	static boolean threecolor=false; // 카드 3장이 모두 같은 색인지 판단
	static boolean fournumber=false; // 4장의 숫자가 같은 경우
	static boolean threenumber=false; // 3장의 숫자가 같은 경우
	/*
	 * 2장의 숫자가 같은 경우은 최대 두 번 발생할 수 있기 때문에
	 * 이를 확인하는 변수는 int형으로 선언하고 각 수를 저장하기 위해 크기가 2인 배열을 사용한다.
	 */
	static int twonumber=0; 
	static int[] two=new int[2];
	static int value=0,answer=0,count=0;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		for(int i=0;i<5;i++) {
			String ch=sc.next();
			int num=sc.nextInt();
			
			// 색깔
			switch(ch) {
			case "R":
				color[0]++;
				break;
			case "B":
				color[1]++;
				break;
			case "G":
				color[2]++;
				break;
			case "Y":
				color[3]++;
				break;
			}
			// 숫자
			number[num]++;
			cardvalue[i]=num;
		}
		
		Arrays.sort(cardvalue);
		Arrays.sort(two);
		continuescard();
		checkcolor();
		checknumber();
		
		// 카드 5장이 모두 같은 색이면서 숫자가 연속적인 경우
		if(continuous==true&&fivecolor==true) {
			answer+=cardvalue[4]+900;
		}
		// 카드 5장 중 4장의 숫자가 같은 경우
		else if(fournumber==true) {
			answer+=value+800;
		}
		// 카드 5장 중 3장의 숫자가 같고 나머지 2장도 숫자가 같은 경우
		else if(threenumber==true&&twonumber==1) {
			answer+=(value*10)+two[0]+700;
		}
		// 5장의 카드 색깔이 모두 같은 경우
		else if(fivecolor==true) {
			answer+=cardvalue[4]+600;
		}
		// 카드 5장의 숫자가 연속적은 경우
		else if(continuous==true) {
			answer+=cardvalue[4]+500;
		}
		// 카드 5장 중 3장의 숫자가 같은 경우
		else if(threenumber==true) {
			answer+=value+400;
		}
		// 카드 5장 중 2장의 숫자가 같고 또 다른 2장의 숫자가 같은 경우
		else if(twonumber==2) {
			answer+=(two[1]*10)+two[0]+300;
		}
		// 카드 5장 중 2장의 숫자가 같은 경우
		else if(twonumber==1) {
			answer+=two[0]+200;
		}
		// 위의 어떤 경우에도 해당하지 않은 경우
		else {
			answer+=cardvalue[4]+100;
		}
		
		System.out.println(answer);
	}
	
	// 카드 숫자가 4개가 같은지, 3개가 같은지, 2개가 같은지 확인하는 함수
	public static void checknumber() {
		for(int i=1;i<10;i++) {
			if(number[i]==4) {
				fournumber=true;
				value=i;
			}
			else if(number[i]==3) {
				threenumber=true;
				value=i;
			}
			/*
			 * 카드의 숫자가 2가가 같은 경우는 최대 두 번
			 * 발생할 수 있기 때문에 각각의 수를 배열에 저장
			 */
			else if(number[i]==2) {
				twonumber++;
				two[count++]=i;
			}
		}
		
	}
	
	// 카드의 색이 모두 같은지, 3장의 색이 같은지 확인하는 함수
	public static void checkcolor() {
		for(int i=0;i<4;i++) {
			// 카드 5장의 색이 모두 같은 경우
			if(color[i]==5) {
				fivecolor=true;
				break;
			}
			// 카드 3장의 색이 모두 같은 경우
			if(color[i]==5) {
				threecolor=true;
				break;
			}
		}
	}
	
	// 카드의 숫자가 연속적인지 판별하는 함수
	public static void continuescard() {
		for(int i=1;i<cardvalue.length;i++) {
			if(cardvalue[i]!=cardvalue[i-1]+1) {
				continuous=false;
				break;
			}
		}
	}
}

 

[코드]

 이번 문제는 난이도는 어렵지 않았지만 구현해야 하는 조건도 많고, 경우에 따라 선언해야 하는 변수가 다 달라 오류를 범할 수 있는 부분이 많은 문제였다. 경우마다 모두 구현하는 방법으로 해결했기 때문에 코드의 줄도 길어지도 깔끔하지 않아 아쉽다.