백준 16986 - 인싸들의 가위바위보(Java)
알고리즘/백준

백준 16986 - 인싸들의 가위바위보(Java)

www.acmicpc.net/problem/16986

 

16986번: 인싸들의 가위바위보

두 사람이 같은 손동작을 내어 무승부가 발생할 경우 경기 진행 순서상 뒤인 사람이 이긴 것으로 간주함에 다시 한 번 유의한다. 구체적으로, 경기 진행 순서는 지우, 경희, 민호 순으로 고정되

www.acmicpc.net

1. 유형

시뮬레이션

 

2. 구현

 

자료구조

  • 딱히 없는듯, 2차원 배열정도..

구현해야 할 기능

  • 지우가 낼 수 있는 모든 손동작(순열)
  • 각 라운드의 승패 판단
  • 다음 플레이어가 누구인지

3. 풀이

 

코딩이 어렵다기 보다는 문제 이해가 너무 어려웠다.

 

주의할 점은 2가지 이다.

 

입력값 20개는 각 라운드의 입력값이 아닙니다.

즉, 만약 경희가 2라운에 대결을 하고 졌을 경우, 3라운드를 넘기고 4라운드에 다시 경기를 한다.

이떄 입력값의 4번쨰 요소를 다루는 것이 아닌, 3번쨰 요소를 입력값으로 다뤄야한다.

라운드를 넘어간다고 입력값도 넘기면 안된다. 

요약하면 20개의 입력값이 라운드를 의미하지 않는다.

 

또한 처음 순서는 지우, 경의, 민호 순서이다. 이 순서가 무승부 판단에 중요한 요소이다.

지우 VS 경의 -> 무승부 -> 지우 승

지우 VS 민호 -> 무승부 -> 지우 승

민호 VS 경희 -> 무승부 -> 경희 승

딱 이 3가지 밖에 없다. 각 라운드에 참여하는 순서가 아닌 초기의 게임 진행 순서가 무승부 판단의 요소이기 떄문.

 

풀이....

지우는 각각 다른 손동작을 내야한다. 그러므로 중복하지 않는 순열을 사용해서 n가지의 다른 손동작을 먼저 구해서 배열에 저장.

 

위의 2가지 주의 할 점을 파악하면 나머지는 그냥 반복문으로 구현하면 된다.

끝...

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {
	static int N, K, map[][], round[][], win[];
	static boolean visit[], flag;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine());
		N = Integer.valueOf(st.nextToken());
		K = Integer.valueOf(st.nextToken());
		map = new int[N + 1][N + 1];
		for (int i = 1; i <= N; i++) {
			st = new StringTokenizer(in.readLine());
			for (int j = 1; j <= N; j++) {
				map[i][j] = Integer.valueOf(st.nextToken());
			}
		}
		flag = false;
		win = new int[4];
		visit = new boolean[N + 1];
		round = new int[4][21];
		for (int i = 2; i <= 3; i++) {
			st = new StringTokenizer(in.readLine());
			for (int j = 1; j <= 20; j++) {
				round[i][j] = Integer.valueOf(st.nextToken());
			}
		}
		perm(1);
		if (flag)
			System.out.println(1);
		else
			System.out.println(0);
	}

	static void perm(int dep) {
		if (flag) {
			return;
		}
		if (dep == N + 1) {
			game();
			return;
		}
		for (int i = 1; i <= N; i++) {
			if (!visit[i]) {
				visit[i] = true;
				round[1][dep] = i;
				perm(dep + 1);
				visit[i] = false;
			}
		}
	}

	static void game() {
		int index[] = new int[4];
		for(int i=1; i<=3; i++)
			index[i]=1;
		int p1 = 1;
		int p2 = 2;
		int np = 3;
		int win[] = new int[4];
		while (true) {
			np = 6 - (p1 + p2);
			if (win[1] == K) {
				flag = true;
				return;
			}
			if (win[2] == K || win[3] == K) {
				return;
			}
			if (index[1] == N + 1) {
				return;
			}
			if (index[2] == 21 || index[3]==21) {
				return;
			}

			int cmd1 = round[p1][index[p1]];
			int cmd2 = round[p2][index[p2]];
			int winner = winCheck(cmd1, cmd2, p1, p2);
			win[winner]++;
			index[p1]++;
			index[p2]++;
			p1 = winner;
			p2 = np;

		}
	}

	static int winCheck(int cmd1, int cmd2, int p1, int p2) {
		if (map[cmd1][cmd2] == 2) {
			return p1;
		} else if (map[cmd1][cmd2] == 1) {
			return Math.max(p1, p2);
		} else {
			return p2;
		}
	}
}

4. 느낀점

문제 이해만 몇십분을 쓴건지 모르곘다.

책을 읽어야하나...

 

'알고리즘 > 백준' 카테고리의 다른 글

백준 17836 - 공주님을 구해라!(Java)  (0) 2021.01.24
백준 2304 - 창고 다각형(Java)  (0) 2021.01.24
백준 20207 - 달력(Java)  (0) 2021.01.17
백준 16722 - 결! 합!  (0) 2021.01.16
백준 6051 - 시간 여행(Java)  (1) 2021.01.15