https://www.acmicpc.net/problem/4991
4991번: 로봇 청소기
각각의 테스트 케이스마다 더러운 칸을 모두 깨끗한 칸으로 바꾸는 이동 횟수의 최솟값을 한 줄에 하나씩 출력한다. 만약, 방문할 수 없는 더러운 칸이 존재하는 경우에는 -1을 출력한다.
www.acmicpc.net
kks227 블로그 따라가며 알고리즘 다시 익히는 중이다. 비트마스킹을 되게 재밌게 했었는데 기억이 안나서 감잡기 문제.
접근 방법
딱 봐서 bfs문제인데, 방문했던 칸을 다시 방문할 수 있다는 조건이 존재한다. 1194번 문제랑 비슷하게, 현재 방문한 상태를 저장하는 변수 하나를 큐에 같이 넣어서 탐색하면 된다.
'n*m 배열의 최단거리' + '특정 지점 모두 방문' 두 조건이 붙으면 bfs+비트마스킹으로 푸는 정석인 것 같음.
청소할 곳이 10개밖에 안되므로 1<<10 * 20 * 20 크기의 visited 배열을 사용하므로 메모리도 문제없다.
풀이
tag : bfs, bitmasking
#include<iostream>
#include<queue>
#include<utility>
#include<string.h>
using namespace std;
const int dy[4]={-1,0,1,0};
const int dx[4]={0,1,0,-1};
int w,h;
char arr[21][21];
int visited[1<<10][21][21];
int cnt=0;
typedef struct info{
int bit;
int r;
int c;
}info;
int bfs(int r,int c){
int depth=0;
info initInfo = {0,r,c};
queue<info> q;
q.push(initInfo);
visited[0][r][c]=1;
while(!q.empty()){
int qs=q.size();
for(int i=0;i<qs;i++){
info deq=q.front();
q.pop();
if(deq.bit== (1<<cnt) -1){
return depth;
}
for(int j=0;j<4;j++){
int nr=deq.r+dy[j];
int nc=deq.c+dx[j];
if(nr<0 || nc<0 || nr>=h | nc>=w || arr[nr][nc]=='x')
continue;
if(visited[deq.bit][nr][nc]==1) //현재 단계에서 방문
continue;
char dest = arr[nr][nc];
info newInfo;
if(dest>=0 && dest<=9){ //더러운곳
/*
if(deq.bit & 1<<dest) //지금까지 방문한 더러운곳은 갈필요 없다
continue; //방문한 더러운곳을 다시 되돌아가는경우가있음.
*/
//방문한적없는 더러운곳
newInfo = {deq.bit | 1<<dest, nr, nc};
}
else { //방문한적없는 일반 땅
newInfo = {deq.bit, nr, nc};
}
q.push(newInfo);
visited[newInfo.bit][newInfo.r][newInfo.c]=1;
}
}
depth++;
}
return -1;
}
int main(){
int sr,sc;
while(1){
cnt=0;
cin>>w>>h;
if(!w)
return 0;
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
cin>>arr[i][j];
if(arr[i][j]=='o')
sr=i,sc=j;
if(arr[i][j]=='*')
arr[i][j]=cnt++;
}
}
memset(visited,0,sizeof(visited));
cout<<bfs(sr,sc)<<endl;
}
}
코드 중간에 /* */ 주석으로 처리한 부분때문에 30분정도 반례를 뒤졌다.
더러운 곳을 방문할 때 이미 청소한 곳이어도 지나갈 수 있는데, 지나가지 못하게 했다..조심
'Algorithm > BOJ' 카테고리의 다른 글
[백준/BOJ] 1167 트리의 지름 - 접근과 풀이 (c++) (0) | 2022.10.01 |
---|---|
[백준/BOJ] 1536 개근상 - 접근과 풀이 (c++) (0) | 2022.09.30 |
[백준/BOJ] 20957 농부 비니 - 접근과 풀이 (c++) (0) | 2022.09.19 |
[백준/BOJ] 9019 DSLR - 접근과 풀이 (c++) (1) | 2022.09.16 |
[백준/BOJ] 2580 스도쿠 - 접근과 풀이 (c++) (0) | 2022.09.16 |