Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 알고리즘
- 쿠쉬쿠쉬
- Lv.1
- OS
- 면접질문
- Lv.2
- 고득점Kit
- 코딩테스트
- C++
- 문제풀이
- 이분그래프판별
- LV.3
- BFS
- C
- 그래프
- 프로그래머스
- 해시
- 운영체제
- 단지번호붙이기
- Python
- BruteForceSearch
- Java
- hash
- 코딩테스트준비
- 2색칠하기
- Algorithm
- 동적계획법
- 파이썬
- 코테준비
Archives
- Today
- Total
쿠쿠의기록
19. 목수의 미로 탈출 본문
문제
아래와 같이 이동할 수 있는 길, 그리고 이동할 수 없는 벽으로 이루어진 크기 N x M 의 지도가 주어진다. 이 때, (N-1, 0) 에서 출발하여 (0, M-1) 까지 도착하는 최단거리를 찾으려 한다. 그런데 목수는 도끼 하나를 갖고 있으며, 이 도끼를 이용하여 벽을 깨부술 수 있다. 하지만 이 도끼는 내구성이 그렇게 좋지 않기 때문에, 벽을 최대 1개밖에 깰 수 없다. 목수가 출발점에서 도착점까지 이동하기 위한 최단거리를 출력하는 프로그램을 작성하시오. 물론, 벽은 최대 1개까지 깰 수 있다. 아래 예제의 경우 ‘X’ 로 표시된 벽을 깰 경우 거리 18만에 출발점에서 도착점으로 이동할 수 있다.
입력
첫째 줄에 지도의 세로 길이 N과 지도의 가로 길이 M이 주어진다. ( 1 ≤ N, M ≤ 1,000 ) 둘째 줄부터 지도의 정보가 주어진다. 0은 이동할 수 있는 부분, 1은 이동할 수 없는 부분을 나타낸다.
출력
목수가 (N-1, 0) 에서 출발하여 (0, M-1) 까지 이동하는 데 필요한 최단거리를 출력한다. 목수는 미로를 항상 탈출할 수 있다고 가정한다.
예제 입력
10 10
0 0 0 0 0 0 1 1 0 0
0 1 1 1 0 0 1 0 1 0
0 1 1 1 0 0 1 0 1 0
0 0 0 0 0 0 0 0 1 0
0 0 1 1 1 1 0 0 1 0
0 0 0 0 0 0 1 1 0 0
0 0 1 1 1 0 1 1 0 0
0 0 1 1 1 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 1 0 0
예제 출력
18
예제 입력
10 10
0 0 0 0 0 0 1 1 0 0
0 1 1 1 0 0 1 1 1 0
0 1 1 1 0 0 1 1 1 0
0 0 0 0 0 0 0 1 1 0
0 0 1 1 1 1 0 1 1 0
0 0 0 0 0 0 1 1 0 0
0 0 1 1 1 0 1 1 0 0
0 0 1 1 1 0 0 1 0 0
0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 1 0 0
예제 출력
22
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX = 1005;
int arr[MAX][MAX];
int check[MAX][MAX];
int n,m;
int checkR[MAX][MAX];
typedef struct coor{
int n;
int m;
coor(){};
coor(int _n,int _m):n(_n),m(_m){};
}coor;
queue <coor> q;
int dx[4] = {0,-1,1,0};
int dy[4] = {1,0,0,-1};
bool inside(int a,int b){
return (a>=0 && a<n) && (b>=0&&b<m);
}
int flag = 0;
int cnt = 0;
void BFS(){
if(q.empty()&&flag!=0) return;
coor now = q.front();
q.pop();
int a,b;
a = now.n;
b = now.m;
int temp = check[a][b];
int nx,ny;
for(int i=0;i<4;i++){
nx = a+dx[i];
ny = b+dy[i];
if(inside(nx,ny)&&check[nx][ny]==0&&arr[nx][ny]!=1){
now.n = nx;
now.m = ny;
q.push(now);
check[nx][ny] = temp+1;
}
}
if(!q.empty() && flag==0) BFS();
}
void BFS_R(){
if(q.empty()&&flag!=0) return;
coor now = q.front();
q.pop();
int a,b;
a = now.n;
b = now.m;
int temp = checkR[a][b];
int nx,ny;
for(int i=0;i<4;i++){
nx = a+dx[i];
ny = b+dy[i];
if(inside(nx,ny)&&checkR[nx][ny]==0&&arr[nx][ny]!=1){
now.n = nx;
now.m = ny;
q.push(now);
checkR[nx][ny] = temp+1;
}
}
if(!q.empty() && flag==0) BFS_R();
}
int main(){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&arr[i][j]);
}
}
check[n-1][0] = 1;
q.push(coor(n-1,0));
BFS();
checkR[0][m-1] = 1;
q.push(coor(0,m-1));
BFS_R();
int min = 987987987;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int sm=987987987,em=987987987;
if(arr[i][j]==1){
int nx, ny;
for(int q=0;q<4;q++){
nx = i+dx[q];
ny = j+dy[q];
if(inside(nx,ny)){
if(sm>check[nx][ny] && check[nx][ny]!=0) sm = check[nx][ny];
if(em>checkR[nx][ny] && checkR[nx][ny]!=0) em = checkR[nx][ny];
if(min>sm+em) min = sm+em;
}
}
}
}
}
printf("%d",min);
return 0;
}
'알고리즘 > L19 BFS,DFS' 카테고리의 다른 글
19. 전염병 (0) | 2023.07.19 |
---|---|
19. 이상한 계산기 (0) | 2023.07.19 |
19. 단지 번호 붙이기 (0) | 2023.07.11 |
19. 미로 찾기 (0) | 2023.07.05 |
19. 웜 바이러스 (0) | 2023.07.04 |