제민
17244 아맞다우산 (비트마스킹) 본문
https://www.acmicpc.net/problem/17244
17244번: 아맞다우산
경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. "아 맞다 우산!!!" 경재 씨는 매번 외출
www.acmicpc.net
챙겨야 하는 물건의 수가 최대 5개로 작으므로 비트마스크를 사용해 해결할 수 있다.
#include <bits/stdc++.h>
using namespace std;
int N,M,Bit,idx;
bool vis[53][53][35]; //y x bit
char board[53][53];
int dy[4]={1,0,-1,0};
int dx[4]={0,1,0,-1};
queue<tuple<int,int,int,int>> Q; //y x cnt bit
int main(void){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>N>>M; //가로 세로
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
cin>>board[i][j];
if(board[i][j]=='S'){Q.push(make_tuple(i,j,0,0)); vis[i][j][0]=true;}
if(board[i][j]=='X'){board[i][j]=(idx++)+'0';}
}
}
Bit=(1<<idx)-1;
//idx는 X의 갯수임
//X가 4개라면 Bit==15
//이를 2진수로 바꾸면 1111이므로 한 자리당 X 한 개를 의미한다.
while(!Q.empty()){
auto cur=Q.front(); Q.pop();
int curY,curX,curCnt,curBit;
tie(curY,curX,curCnt,curBit)=cur;
if(board[curY][curX]=='E'&&curBit==Bit){
cout<<curCnt<<'\n';
break;
}
for(int dir=0;dir<4;dir++){
int ny=curY+dy[dir];
int nx=curX+dx[dir];
int nb=curBit;
if(ny<0||nx<0||ny>=M||nx>=N) continue;
if(board[ny][nx]=='#') continue;
if(board[ny][nx]>='0' && board[ny][nx]<='4'){nb|=(1<<(board[ny][nx]-'0'));}
if(vis[ny][nx][nb]) continue;
vis[ny][nx][nb]=true; Q.push(make_tuple(ny,nx,curCnt+1,nb));
}
}
return 0;
}
비트마스크를 사용해 문제를 푼 건 이게 처음인데 굉장히 신박한 방식이라고 느꼈다.
'코테연습일지 > 그래프 이론' 카테고리의 다른 글
5558 チーズ (Cheese) (0) | 2024.03.02 |
---|---|
14923 미로 탈출 (0) | 2024.03.02 |
16234 인구 이동 (0) | 2024.02.11 |
16985 Maaaaaaaaaze (2) | 2024.02.08 |
17141 연구소 2 (0) | 2024.02.07 |