[백준] 8896: 가위 바위 보 (Java)

Yoon Uk·2022년 7월 7일
0

알고리즘 - 백준

목록 보기
20/130
post-thumbnail

문제

BOJ 8896: 가위 바위 보 https://www.acmicpc.net/problem/8896

풀이

  • LinkedList에는 가위바위보에 참가할 수 있는 로봇의 번호를 넣어준다.
  • HashMap에는 LinkedList에 있는 로봇의 번호로봇이 낸 결과(가위/바위/보)를 넣는다.
    • Key 값으로 로봇의 번호를, Value 값으로 로봇이 낸 결과(가위/바위/보)를 넣는다.
  • LinkedList에 남아 있는 값 갯수, 즉 게임에 참가할 수 있는 로봇의 갯수 만큼 반복하며 가위/바위/보 중 몇 종류의 결과가 나왔는지 알아낸다.
    • 가위/바위/보 모두 나오거나 한 종류만 나온다면 무승부가 된다. -> continue;
    • 가위/바위/보 중 2 종류만 나온다면 승부를 가릴 수 있게 된다.
      • 가위/바위 만 나온 경우 가위를 낸 로봇은 LinkedListHashMap에서 삭제한다.
      • 바위/종이 만 나온 경우 바위를 낸 로봇은 LinkedListHashMap에서 삭제한다.
      • 종이/가위 만 나온 경우 종이를 낸 로봇은 LinkedListHashMap에서 삭제한다.
  • LinkedList에 남아 있는 로봇의 수가 1이 된다면 그 로봇이 승자가 된다.
  • LinkedList에 남아 있는 로봇의 수가 1보다 크다면 승자가 없게 된다.

코드

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

public class Main {
	
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		//Scanner sc = new Scanner(System.in);
		
		int T = Integer.parseInt(br.readLine());
		for(int tc = 1; tc <= T; tc++) {
			LinkedList<Integer> list = new LinkedList<>(); // 남아 있는 로봇 넣을 리스트
			
			int N = Integer.parseInt(br.readLine()); // 로봇 갯수
			String[] robot = new String[N];
			
			for(int i=0; i<N; i++) {
				robot[i] = br.readLine();
				list.add(i);
			}

			for(int i=0; i<robot[0].length(); i++) { // 가위바위보 하는 횟수만큼 반복
				HashMap<Integer, Character> map = new HashMap<>(); // 로봇 번호와 낸 가위바위보 넣을 맵
				// 리스트에 남아 있는 로봇들의 번호와 낸 가위바위보 결과를 맵에 넣음
				for(int j=0; j<list.size(); j++) { // 리스트에 남아 있는 로봇 갯수만큼 반복
					int numRobot = list.get(j); // 리스트에 있는 로봇 번호
					char result = robot[numRobot].charAt(i);
					map.put(numRobot, result);
				}
				
				// 리스트에 남아 있는 값 갯수만큼 반복하며 몇 종류의 결과가 있는지 확인
				int kindCnt = 0;
				char[] kindRSP = new char[3]; // '가위 / 바위 / 보' 순서로 들어감
				for(int j=0; j<list.size(); j++) {
					int num = list.get(j);
					char c = map.get(num);
					switch(c) {
						case 'S': kindRSP[0]++;
							break;
						case 'R': kindRSP[1]++;
							break;
						case 'P': kindRSP[2]++;
							break;
					}
				}
				for(int j=0; j<3; j++) {
					if(kindRSP[j] != 0) {
						kindCnt++;
					}
				}
				
				// 묵찌빠 다 나오면 다음 단계로 넘어감 or 모두 같은 거 나오면 다음 단계로 넘어감
				if(kindCnt == 3 || kindCnt == 1) {
					continue;
				} else if(kindCnt == 2) { // 승자 패자가 무조건 나오는 경우
					
					// 가위 바위만 나온 경우
					if(kindRSP[2] == 0) {
						for(int j=list.size()-1; j>=0; j--) {
							int robotNum = list.get(j); // 남아 잇는 로봇 번호
							char robotResult = map.get(robotNum); // 그 로봇 번호가 낸 결과
							if(robotResult == 'S') { // 가위 바위만 나온 경우에서 가위를 낸 로봇은 삭제
								list.remove(j);
								map.remove(robotNum);
							}
						}
					} else if(kindRSP[0] == 0) { // 바위 종이만 나온 경우
						for(int j=list.size()-1; j>=0; j--) {
							int robotNum = list.get(j); // 남아 잇는 로봇 번호
							char robotResult = map.get(robotNum); // 그 로봇 번호가 낸 결과
							if(robotResult == 'R') { // 바위 종이만 나온 경우에서 바위를 낸 로봇은 삭제
								list.remove(j);
								map.remove(robotNum);
							}
						}	
					} else if(kindRSP[1] == 0) { // 종이 가위만 나온 경우
						for(int j=list.size()-1; j>=0; j--) {
							int robotNum = list.get(j); // 남아 잇는 로봇 번호
							char robotResult = map.get(robotNum); // 그 로봇 번호가 낸 결과
							if(robotResult == 'P') { // 종이 가위만 나온 경우에서 종이를 낸 로봇은 삭제
								list.remove(j);
								map.remove(robotNum);
							}
						}	
					}
						
					
				}
				if(list.size() == 1) {
					System.out.println(list.get(0) + 1);
					break;
				}
			}
			

			if(list.size() > 1) { // 승자가 없는 경우
				System.out.println(0);
			}
				
			
		} // 테스트케이스 반복

	}
}

정리

  • 아래 코드에서 for(int j=list.size()-1; j>=0; j--)for문 안쪽을
    처음에 for(int j=0; j<list.size(); j++) 이렇게 해서 틀렸었다.

    LinkedList에서 앞 쪽 값을 제거하면 인덱스가 앞으로 당겨지기 때문이었다.

~~~
// 가위 바위만 나온 경우
if(kindRSP[2] == 0) {
	for(int j=list.size()-1; j>=0; j--) {
		int robotNum = list.get(j); // 남아 잇는 로봇 번호
		char robotResult = map.get(robotNum); // 그 로봇 번호가 낸 결과
		if(robotResult == 'S') { // 가위 바위만 나온 경우에서 가위를 낸 로봇은 삭제
			list.remove(j);
			map.remove(robotNum);
		}
	}
}
~~~

0개의 댓글