본문 바로가기
PS

백준 - 17204 죽음의 게임

by suhsein 2024. 11. 5.
728x90

[Silver III] 죽음의 게임 - 17204

문제 링크

성능 요약

메모리: 2020 KB, 시간: 0 ms

분류

그래프 이론, 그래프 탐색, 구현

제출 일자

2024년 4월 2일 22:33:39

문제 설명

중앙대학교 소프트웨어대학 새내기들을 맞이하게 된 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을 출력한다.

풀이과정

쉬운 문제인데 난독증이 있나 문제 이해하는데 생각을 좀 했다;; 이럴 때는 그림을 그려서 풀면 쉽다.
그래프 문제라고 파악됐고, 0번부터 탐색을 시작하여 노드를 거치면서 답을 증가시키고, K번을 만나는 순간 탐색을 멈추도록 하였다.
탐색은 bfs로 하였고, 답이 없는 경우도 있어서 예외 처리가 필요하다. 예외처리를 위한 visit 배열을 만들었다.

다음 노드 저장하기

0번부터 N-1번까지 노드들이 지목하는 노드가 다음 노드가 된다. 탐색을 위해 다음 노드를 저장한다.
edge[i] = i가 지목하는 다음 노드

탐색하기

bfs를 택했으므로, 큐에 0번 노드를 넣고, 방문처리를 해준다.
그리고 탐색을 시작한다.

종료조건

탐색 완료

큐에서 꺼낸 현재 노드가 K인 경우 종료한다.

탐색 불가능

이미 방문했던 노드가 다음 노드라면, 사이클이 만들어지므로 영원히 K에 접근할 수 없다. 이때는 -1을 출력하고 종료한다.

다음 노드 큐에 넣기

현재 노드의 edge로부터 다음 노드를 찾아 큐에 넣고 방문처리한다.
그리고 현재 노드에서 K를 발견하지 못 했으므로 답을 증가시킨다.

코드

#include <iostream>
#include <queue>
using namespace std;
int N, K, x, edge[160], ans;
bool visit[160];
queue<int> q;
int main(void) {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> N >> K;
    for (int i = 0; i < N; i++) {
        cin >> x;
        edge[i] = x;
    }
    q.push(0); visit[0] = 1;
    while (!q.empty()) {
        int cur = q.front(); q.pop();
        if (cur == K) break;
        int nxt = edge[cur];
        if (visit[nxt]) {
            cout << -1;
            return 0;
        }
        q.push(edge[cur]); visit[nxt] = 1; ans++;
    }
    cout << ans;
}
728x90

'PS' 카테고리의 다른 글

백준 - 12904 A와 B  (0) 2024.11.05
백준 - 2891 카약과 강풍  (0) 2024.11.05
프로그래머스 - 금과 은 운반하기  (0) 2024.11.05
프로그래머스 - 순위  (0) 2024.11.05
프로그래머스 - 퍼즐 조각 채우기  (0) 2024.11.05