https://www.acmicpc.net/problem/17204
17204번: 죽음의 게임
중앙대학교 소프트웨어대학 새내기들을 맞이하게 된 17학번 김영기는 두 학번이라는 차이를 극복하기 위해 새내기들과 친해지려고 노력하고 있다. 그 노력 중 하나는 바로 새내기들과의 술자
www.acmicpc.net
* 문제 요약
중앙대학교 소프트웨어 대학 새내기들을 맞이하게 된 17학번 김영기는 두 학번이라는 차이를 극복하기 위해 새내기들과 친해지려고 노력하고 있다. 그 노력 중 하나는 바로 새내기들과의 술자리에 참여하는 것이다.
그러나 혼자 가기에 민망했던 영기는 동기 보성이를 꼬셔 같이 술자리에 참석했다. 새내기들과 같이 술을 마시게 된 영기와 보성이는 분위기가 가라 앉을 때 쯤 The Game of Death 라고 불리는 죽음의 술게임을 제안한다.
죽음의 게임의 룰은 간단하다.
게임에 참여하는 N명의 사람들은 원탁에 둘러앉게 된다. 게임을 시작하는 사람은 0번, 그 오른쪽 사람은 1번, 그 오른쪽은 2번, N - 1번의 오른쪽 사람은 다시 0번이 된다.
0번이 "신난다! 아싸 재미난다! 아싸 더 게임 오브 데!스!" 라고 외침과 동시에, 모든 사람들은 각각 테이블에 둘러 앉은 사람들 중 한 명을 지목한다. 그리고 나서 0번은 임의의 양의 정수 M을 외친다.
그 다음, 0번은 "1" 이라고 말한다. 이때 "1" 이라고 말한 사람이 지목한 사람은 "2" 라고 말하고, "2" 라고 말한 사람이 지목한 사람은 "3" 이라고 말하고, 같은 방식으로 반복해 M까지 말하게 된다.
이때 마지막으로 M이라고 말한 사람이 지목한 사람은 벌주를 마시게 된다.
새내기에게 벌주를 마시게 하기에는 죄책감이 들었던 영기는 동기인 보성이를 공격하기로 결심했다. 게임 참여자들 간에 지목을 완료한 상태가 주어질 때, 보성이가 벌주를 마시기 위해 영기가 불러야 하는 가장 작은 양의 정수 M을 보성이 몰래 귀띔해주자.
김영기는 게임을 제안하였기에 자연스럽게 0번이 된다.
* 입력
첫 번째 줄에 게임에 참여하는 사람의 수 N(3 <= N <= 150) 과 보성이의 번호 K (1 <= K <= N - 1) 가 공백을 두고 주어진다.
두 번째 줄부터 N줄에 걸쳐 i (0 <= i <= N - 1) 번 사람이 지목하는 사람의 번호 ai(0 <= ai <= N - 1) 가 주어진다.
자기 자신을 지목하는 경우도 존재할 수 있다.
* 출력
영기가 말해야 하는 가장 작은 양의 정수 M을 출력한다. 만약 어떤 방법으로도 보성이가 걸리지 않는다면 -1을 출력한다.
* 예시
* 해결 과정
어떤 숫자를 M으로 지정해도 보성이가 걸리지 않게되는 경우를 잘 파악해야 하는 문제이다.
입력받은 정보를 토대로 DFS 탐색으로 숫자를 1부터 늘려나간다. 이미 방문했던 곳에 다시 방문하게 되기 전에 보성이가 지목받아서 특정 숫자를 부르게 되면 해당 숫자를 출력한다.
만약 보성이가 앉은 자리가 지목되기 전에 이미 지목된 사람이 다시 지목되면 어떤 숫자를 M으로 지정해도 보성이가 걸리지 않게된다는 뜻이므로 -1을 출력해준다.
* 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws IOException {
new Main().solution();
}
static int[] students;
static boolean[] visited;
static int number = 0;
static int bosung;
static boolean check = true;
private void solution() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] input = br.readLine().split(" ");
int n = Integer.parseInt(input[0]);
bosung = Integer.parseInt(input[1]);
students = new int[n];
for (int i = 0; i < n; i++) {
students[i] = Integer.parseInt(br.readLine());
}
visited = new boolean[students.length];
dfs(0);
if (check) {
bw.write(number + "\n");
} else {
bw.write(-1 + "\n");
}
bw.flush();
bw.close();
br.close();
}
private void dfs(int index) {
if (visited[index]) {
check = false;
return;
} else {
visited[index] = true;
if (index != bosung) {
dfs(students[index]);
number++;
} else {
return;
}
}
}
}
배열에 각 번호의 사람이 지목하는 사람의 번호를 저장하고 해당 번호를 토대로 0번부터 인덱스를 탐색하면서 보성이가 앉은자리가 지목되는지 탐색하는데, 이때 탐색의 형태가 인덱스 번호와 해당 인덱스에 저장되어 있는 값을 기준으로 메소드 재귀호출을 통해 수직적인 모습을 가지게 되므로 그래프 탐색(DFS) 문제에 해당된다.
'코딩 테스트 > 그래프' 카테고리의 다른 글
백준 1012 - 유기농 배추 (자바 - 그래프) (0) | 2023.07.19 |
---|---|
백준 4963 - 섬의 개수 (자바 - 그래프) (0) | 2023.07.19 |
백준 15886 - 내 선물을 받아줘2(자바 - 그래프) (0) | 2023.07.13 |
백준 2606 - 바이러스 (자바 - 그래프) (0) | 2023.07.12 |
백준 14397 - 해변 (자바 - 그래프) (0) | 2023.07.12 |