fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 17836 (C++) 공주님을 구해라!
최초 업로드: 2025-04-13 05:22:51
최근 수정 시간: 2025-07-25 09:59:23
게시자: rlatjwls3333
카테고리: 백준
조회수: 8
# [Gold V] 공주님을 구해라! #### [문제 링크](https://www.acmicpc.net/problem/17836) ## 문제 설명 <p>용사는 마왕이 숨겨놓은 공주님을 구하기 위해 (<em>N</em>, <em>M</em>) 크기의 성 입구 (1,1)으로 들어왔다. 마왕은 용사가 공주를 찾지 못하도록 성의 여러 군데 마법 벽을 세워놓았다. 용사는 현재의 가지고 있는 무기로는 마법 벽을 통과할 수 없으며, 마법 벽을 피해 (<em>N</em>, <em>M</em>) 위치에 있는 공주님을 구출해야만 한다.</p> <p>마왕은 용사를 괴롭히기 위해 공주에게 저주를 걸었다. 저주에 걸린 공주는 <em>T</em>시간 이내로 용사를 만나지 못한다면 영원히 돌로 변하게 된다. 공주님을 구출하고 프러포즈 하고 싶은 용사는 반드시 <em>T</em>시간 내에 공주님이 있는 곳에 도달해야 한다. 용사는 한 칸을 이동하는 데 한 시간이 걸린다. 공주님이 있는 곳에 정확히 <em>T</em>시간만에 도달한 경우에도 구출할 수 있다. 용사는 상하좌우로 이동할 수 있다.</p> <p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/62b6063d-4d01-4836-9793-94ab99f032f2/" style="width: 300px; height: 261px;"></p> <p>성에는 이전 용사가 사용하던 전설의 명검 "그람"이 숨겨져 있다. 용사가 그람을 구하면 마법의 벽이 있는 칸일지라도, 단숨에 벽을 부수고 그 공간으로 갈 수 있다. "그람"은 성의 어딘가에 반드시 한 개 존재하고, 용사는 그람이 있는 곳에 도착하면 바로 사용할 수 있다. 그람이 부술 수 있는 벽의 개수는 제한이 없다.</p> <p>우리 모두 용사가 공주님을 안전하게 구출 할 수 있는지, 있다면 얼마나 빨리 구할 수 있는지 알아보자.</p> ## 입력 <p>첫 번째 줄에는 성의 크기인 <em>N</em>, <em>M</em> 그리고 공주에게 걸린 저주의 제한 시간인 정수 <em>T</em>가 주어진다. 첫 줄의 세 개의 수는 띄어쓰기로 구분된다. (3 ≤ <em>N</em>, <em>M</em> ≤ 100, 1 ≤ <em>T</em> ≤ 10000)</p> <p>두 번째 줄부터 <em>N</em>+1번째 줄까지 성의 구조를 나타내는 <em>M</em>개의 수가 띄어쓰기로 구분되어 주어진다. 0은 빈 공간, 1은 마법의 벽, 2는 그람이 놓여있는 공간을 의미한다. (1,1)과 (<em>N</em>,<em>M</em>)은 0이다.</p> ## 출력 <p>용사가 제한 시간 <em>T</em>시간 이내에 공주에게 도달할 수 있다면, 공주에게 도달할 수 있는 최단 시간을 출력한다.</p> <p>만약 용사가 공주를 <em>T</em>시간 이내에 구출할 수 없다면, "<code>Fail</code>"을 출력한다.</p> ## 풀이 #### 그람을 들었을 때와, 들지 않았을 때 2가지로 나누어서 bfs를 돌리면 풀 수 있습니다. ``` c++ #include<bits/stdc++.h> using namespace std; int board[100][100]; bool visited[100][100][2]; // [][][0] : gram=0, [][][1] : gram=1 int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; struct pos { int x, y, gram, cost; }; int main() { ios::sync_with_stdio(0); cin.tie(0); int n, m, t; cin >> n >> m >> t; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin >> board[i][j]; } } int cost=t+1; queue<pos> q; q.push({0, 0, 0, 0}); while(!q.empty()) { pos cur = q.front(); q.pop(); if(cur.x==n-1 && cur.y==m-1) { cost=cur.cost; break; } for(int i=0;i<4;i++) { pos next = {cur.x+dx[i], cur.y+dy[i], cur.gram, cur.cost+1}; if(board[next.x][next.y]==2) next.gram=1; if(next.x<0 || next.x>=n || next.y<0 || next.y>=m || visited[next.x][next.y][next.gram] || next.gram==0 && board[next.x][next.y]==1) continue; visited[next.x][next.y][next.gram]=true; q.push(next); } } if(cost>t) cout << "Fail"; else cout << cost; } ```