Problem : https://www.acmicpc.net/problem/16986
16986번: 인싸들의 가위바위보
두 사람이 같은 손동작을 내어 무승부가 발생할 경우 경기 진행 순서상 뒤인 사람이 이긴 것으로 간주함에 다시 한 번 유의한다. 구체적으로, 경기 진행 순서는 지우, 경희, 민호 순으로 고정되
www.acmicpc.net
Approach
순열을 이용한완전탐색과구현이 필요한 문제였다.
먼저 문제에서 주의할 점을 짚고 가자.
- 입력으로 주어지는
경희와민호의 패는 라운드 별 패가 아니다.경희와민호가 참여하는 게임에서 내는 패의 순서일 뿐이다. 지우가 질 경우에도 사용한 적이 없는 패를 내야한다. (서로 다른 패로 이기는 경우만을 찾는 것이 아니다.)
문제 풀이의 주요 로직은 다음과 같다.
순열을 이용하여지우의 패를 결정한다.지우, 경희, 민호의 패를 이용하여, 게임을 진행하고지우가 이길 수 있는지를 판단한다.
지우가 가지고 있는 패보다 게임을 더 많이 진행할 이유는 없다.
게임을 진행하며, 게임에 참여하는 인원과 게임의 승패 여부를 잘 구현해야 한다.
Code
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
/**
* No.16986: 인싸들의 가위바위보
* Hint: BruteForce + 구현
*/
public class BOJ16986 {
static int n, k;
static int[][] a;
static int[][] commands;
static boolean[] used;
static boolean flag;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
used = new boolean[n + 1]; // 순열 생성에 필요한 배열
a = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= n; j++) {
a[i][j] = Integer.parseInt(st.nextToken());
}
}
commands = new int[4][21];
for (int i = 2; i <= 3; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= 20; j++) {
commands[i][j] = Integer.parseInt(st.nextToken());
}
}
permutation(1);
bw.write(flag ? "1" : "0");
bw.close();
br.close();
}
// 1번 플레이어가 이기면 true, 그러지 못하면 false 리턴
static boolean gameStart() {
int[] winCnt = new int[4];
int[] actionIndex = new int[4];
Arrays.fill(actionIndex, 1);
int player1 = 1, player2 = 2, nextPlayer = 3;
while (true) {
nextPlayer = 6 - player1 - player2;
if (winCnt[1] == k) {
return true;
}
if (winCnt[2] == k || winCnt[3] == k) {
return false;
}
if (actionIndex[1] == n + 1 || actionIndex[2] == 21 || actionIndex[3] == 21) {
return false;
}
int winner = whoWin(player1, player2, actionIndex);
winCnt[winner]++;
actionIndex[player1]++;
actionIndex[player2]++;
player1 = winner;
player2 = nextPlayer;
}
}
// 순열
static void permutation(int depth) {
if (flag) { // 정답을 찾았으면 리턴
return;
}
if (depth == n + 1) {
if (gameStart()) {
flag = true; // 정답 찾음 표시
}
return;
}
// 1번 플레이어의 action 구성
for (int i = 1; i <= n; i++) {
if (!used[i]) {
used[i] = true;
commands[1][depth] = i;
permutation(depth + 1);
used[i] = false;
}
}
}
// 이긴 사람의 번호를 리턴
static int whoWin(int p1, int p2, int[] actionIndex) {
int action1 = commands[p1][actionIndex[p1]];
int action2 = commands[p2][actionIndex[p2]];
if (a[action1][action2] == 2) {
return p1;
} else if (a[action1][action2] == 1) {
return Math.max(p1, p2);
} else {
return p2;
}
}
}'Algorithm > Baekjoon Online Judge' 카테고리의 다른 글
| [Java] 백준 4179 (불!) Gold 4 (0) | 2021.06.28 |
|---|---|
| [Java] 백준 6198 (옥상 정원 꾸미기) Gold 5 (0) | 2021.06.26 |
| [Java] 백준 16985 (Maaaaaaaaaze) Gold 3 (0) | 2021.06.21 |
| [Java] 백준 16957 (체스판 위의 공) Gold 4 (0) | 2021.06.20 |
| [Java] 백준 12931 (두 배 더하기) Gold 4 (0) | 2021.06.19 |