Skip to content

Commit 6b9d3d2

Browse files
committed
[Gold II] Title: 인싸들의 가위바위보, Time: 80 ms, Memory: 79516 KB -BaekjoonHub
1 parent 0cba6bf commit 6b9d3d2

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# [Gold II] 인싸들의 가위바위보 - 16986
2+
3+
[문제 링크](https://www.acmicpc.net/problem/16986)
4+
5+
### 성능 요약
6+
7+
메모리: 79516 KB, 시간: 80 ms
8+
9+
### 분류
10+
11+
구현, 브루트포스 알고리즘, 백트래킹
12+
13+
### 제출 일자
14+
15+
2026년 1월 11일 17:33:14
16+
17+
### 문제 설명
18+
19+
<p>혹시 마지막으로 엠티를 간 것이 언제인가? 엠티를 안간지 꽤 오래됐다면 요즘 유행하는 인싸들의 가위바위보를 모를 것이다. 요즘 인싸들은 엠티에서 평범한 가위바위보를 시시하다는 이유로 더 이상 취급하지 않는다. 대신 가위불바위총번개악마용물공기보스펀지늑대나무사람뱀을 한다. 이 게임의 명칭이 다소 긴 관계로 문제 내에서는 전체 명칭을 적는 대신 이 게임의 또 다른 이름인 인싸 가위바위보로 부르겠다. 인싸 가위바위보는 평범한 가위바위보와 같이 각 손동작간의 상성이 정해져있다. </p>
20+
21+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/6b815187-9cdc-416c-ab42-cf1e2083c972/-/preview/" style="width: 300px; height: 305px;"></p>
22+
23+
<p>인싸 가위바위보는 평범한 가위바위보보다 흥미진진하고 재밌지만 3명 이상이 경기를 할 때 누가 이기고 누가 졌는지를 빠르게 알기 힘들다는 단점이 있다. 그렇기에 3명 이상의 사람들 사이에서 인싸 가위바위보를 할 때는 모두가 동시에 경기를 진행하는 대신 일대일 경기를 여러 번 진행해 누가 우승했는지 판단한다. 3명이서 인싸 가위바위보를 할 때의 우승자를 정하기 위한 구체적인 방식은 아래와 같다. 편의상 참가자 3명을 A, B, C라고 하자.</p>
24+
25+
<ol>
26+
<li>A, B, C는 게임 시작 전 우승을 위해 필요한 승수와 경기 진행 순서를 미리 합의한다. 경기 진행 순서가 A, B, C라고 가정하자.</li>
27+
<li>먼저 A와 B가 경기를 진행해 승자를 결정한다. 만약 두 사람이 같은 손동작을 내어 무승부가 발생할 경우 경기 진행 순서상 뒤인 사람이 이긴 것으로 간주한다. 즉 A와 B가 같은 손동작을 내면 B의 승리, A와 C가 같은 손동작을 내면 C의 승리, B와 C가 같은 손동작을 내면 C의 승리이다. </li>
28+
<li>이전 경기의 승자와 이전 경기에 참여하지 않은 사람이 경기를 진행해 승자를 결정한다.</li>
29+
<li>특정 사람이 미리 합의된 승수를 달성할 때 까지 3을 반복한다.</li>
30+
<li>합의된 승수를 최초로 달성한 사람이 우승한다.</li>
31+
</ol>
32+
33+
<p>밑의 표는 침, 펄, 풍 세 사람이 인싸 가위바위보를 진행하는 예시이다. 우승을 위해 필요한 승수는 3승이고 침, 펄, 풍 순서로 경기를 진행한다.</p>
34+
35+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/cc3ab4c0-b203-44ee-b78a-9c29861a24a1/-/preview/"></p>
36+
37+
<p>인싸 가위바위보 결과 풍이 제일 먼저 3승에 도달했으므로 우승자는 풍이다. 1라운드, 3라운드에서 두 사람이 같은 손동작을 냈을 때 경기 진행 순서상 뒤인 사람이 승리하는 것을 확인할 수 있다.</p>
38+
39+
<p>컴퓨터공학과 새내기 지우는 첫 엠티에서 친구 경희, 민호와 인싸 가위바위보를 할 생각에 굉장히 신나있다. 지우는 경희와 민호의 행동 패턴을 빅데이터로 분석해 인싸 가위바위보를 하는 중 경희와 민호의 차례가 왔을 때 이들이 낼 손동작의 순서를 정확히 알고 있다. 그래서 마음만 먹으면 전승 우승이 가능하지만 경기를 흥미진진하게 이끌기 위해 인싸 가위바위보를 할 때 모든 손동작을 다르게 내고 싶어한다. 지우의 즐거운 대학생활을 위해 인싸 가위바위보의 상성표와 경희, 민호가 낼 손동작의 순서가 주어졌을 때 지우가 모든 손동작을 다르게 내어 우승할 수 있는지 판단하는 프로그램을 만들자. 경기 진행 순서는 지우, 경희, 민호 순으로 정해져있다.</p>
40+
41+
### 입력
42+
43+
<p>첫째 줄에 인싸 가위바위보의 손동작 수를 나타내는 N(1 ≤ N ≤ 9)과 우승을 위해 필요한 승수 K(1 ≤ K ≤ 6)가 한 칸의 빈칸을 사이에 두고 주어진다.</p>
44+
45+
<p>그 다음 N개의 줄에 대해 상성에 대한 정보 <em>A<sub>i,j</sub></em>가 주어진다. i+1번째 줄에는 N개의 정수 <em>A<sub>i,1</sub></em>, <em>A<sub>i,2</sub></em>, <em>A<sub>i,3</sub></em>, ..., <em>A<sub>i,N</sub></em>이 한 칸의 빈칸을 사이에 두고 주어진다. <em>A<sub>i,j</sub></em>가 2일 경우에는 i번 손동작이 j번 손동작을 이긴다는 의미이고, 1일 경우에는 비긴다는 의미이고, 0일 경우에는 진다는 의미이다. <em>A<sub>i,i </sub></em>= 1이고, i ≠ j일 때 <em>A<sub>i,j </sub></em>≠ 1임이 보장된다. 또한 <em>A<sub>i,j</sub></em>가 2일 경우에는 <em>A<sub>j,i</sub></em>가 0이고, <em>A<sub>i,j</sub></em>가 0일 경우에는 <em>A<sub>j,i</sub></em>가 2임이 보장된다.</p>
46+
47+
<p>그 다음 줄에는 경희가 앞으로 자신이 참여하는 20경기에서 낼 손동작의 순서가 한 칸의 빈칸을 사이에 두고 주어진다. 손동작의 번호는 1 이상 N 이하이다.</p>
48+
49+
<p>그 다음 줄에는 민호가 앞으로 자신이 참여하는 20경기에서 낼 손동작의 순서가 한 칸의 빈칸을 사이에 두고 주어진다. 마찬가지로 손동작의 번호는 1 이상 N 이하이다.</p>
50+
51+
### 출력
52+
53+
<p>첫째 줄에 지우, 경희, 민호 순으로 경기를 진행할 때 지우가 모든 손동작을 다르게 내어 우승할 수 있으면 1을, 그렇지 않으면 0을 출력한다.</p>
54+
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import Foundation
2+
3+
let input = readLine()!.split(separator: " ").map { Int($0)! }
4+
let N = input[0]
5+
let K = input[1]
6+
7+
var A = Array(repeating: Array(repeating: 0, count: N), count: N)
8+
for i in 0..<N {
9+
A[i] = readLine()!.split(separator: " ").map { Int($0)! }
10+
}
11+
12+
var seq = Array(repeating: Array(repeating: 0, count: 20), count: 3)
13+
seq[1] = readLine()!.split(separator: " ").map { Int($0)! - 1 }
14+
seq[2] = readLine()!.split(separator: " ").map { Int($0)! - 1 }
15+
16+
var used = Array(repeating: false, count: N)
17+
var win = false
18+
19+
func fight(_ x: Int, _ y: Int, _ a: Int, _ b: Int) -> Int {
20+
if A[a][b] == 2 { return x }
21+
if A[a][b] == 0 { return y }
22+
return max(x, y) // 무승부 → 순서상 뒤
23+
}
24+
25+
func dfs(_ p1: Int, _ p2: Int,
26+
_ w1: Int, _ w2: Int, _ w3: Int,
27+
_ i2: Int, _ i3: Int) {
28+
29+
if win { return }
30+
if w1 >= K {
31+
win = true
32+
return
33+
}
34+
if w2 >= K || w3 >= K { return }
35+
36+
if p1 == 0 || p2 == 0 {
37+
for i in 0..<N {
38+
if used[i] { continue }
39+
used[i] = true
40+
41+
let a = (p1 == 0) ? i : seq[p1][p1 == 1 ? i2 : i3]
42+
let b = (p2 == 0) ? i : seq[p2][p2 == 1 ? i2 : i3]
43+
44+
let winner = fight(p1, p2, a, b)
45+
46+
var nw1 = w1, nw2 = w2, nw3 = w3
47+
var ni2 = i2, ni3 = i3
48+
49+
if winner == 0 { nw1 += 1 }
50+
else if winner == 1 { nw2 += 1 }
51+
else { nw3 += 1 }
52+
53+
if p1 == 1 { ni2 += 1 }
54+
if p1 == 2 { ni3 += 1 }
55+
if p2 == 1 { ni2 += 1 }
56+
if p2 == 2 { ni3 += 1 }
57+
58+
let rest = 3 - p1 - p2
59+
dfs(winner, rest, nw1, nw2, nw3, ni2, ni3)
60+
61+
used[i] = false
62+
}
63+
} else {
64+
let a = seq[p1][p1 == 1 ? i2 : i3]
65+
let b = seq[p2][p2 == 1 ? i2 : i3]
66+
67+
let winner = fight(p1, p2, a, b)
68+
69+
var nw1 = w1, nw2 = w2, nw3 = w3
70+
var ni2 = i2, ni3 = i3
71+
72+
if winner == 0 { nw1 += 1 }
73+
else if winner == 1 { nw2 += 1 }
74+
else { nw3 += 1 }
75+
76+
if p1 == 1 { ni2 += 1 }
77+
if p1 == 2 { ni3 += 1 }
78+
if p2 == 1 { ni2 += 1 }
79+
if p2 == 2 { ni3 += 1 }
80+
81+
let rest = 3 - p1 - p2
82+
dfs(winner, rest, nw1, nw2, nw3, ni2, ni3)
83+
}
84+
}
85+
86+
dfs(0, 1, 0, 0, 0, 0, 0)
87+
print(win ? 1 : 0)

0 commit comments

Comments
 (0)