레야몬
[C++] 9328번 열쇠 - BFS 본문
#include <iostream>
#include <queue>
#include <vector>
#include <string.h>
#define LOOP(i, N) for(int i=1; i<=N; i++)
#define MAX_LEN 105
using namespace std;
int T, h, w; //테스트 케이스이 개수 T, 높이와 너비 h와 w
char map[MAX_LEN][MAX_LEN]; //맵
int key[30]; //알파벳의 개수는 26개
queue<pair<int, int>> q; //좌표 저장
vector<pair<int, int>> ufkey[30]; //열지 못한 문. unfound key
char ks[30];
int xt[5] = {0, 1, 0, -1, 0}; //xturn
int yt[5] = {0, 0, -1, 0, 1};
int main()
{
scanf("%d", &T);
LOOP(i, T) {
int cnt=0;
scanf("%d %d\n", &h, &w); //입력
LOOP(j, h) {
LOOP(k, w+1) {
scanf("%c", &map[j][k]);
if((j==1 || j==h || k==1 || k==w) && k!=w+1) { //테두리에서 길 찾기
switch(map[j][k]) {
case '*': //막혀있음
continue;
case '$': //돈이 있음
cnt++;
case '.': //아직 탐색하지 않음
q.push({j, k}); //큐에 추가
break;
default: {
int tmp = map[j][k];
if(tmp>='a') { //열쇠는 추가
key[tmp-'a']=1;
while(!ufkey[tmp-'a'].empty()) {
q.push({ufkey[tmp-'a'].back().first, ufkey[tmp-'a'].back().second});
ufkey[tmp-'a'].pop_back();
}
q.push({j, k});
}
else { //문이
if(key[tmp-'A']) //열쇠가 있다면 열고 큐에 추가
q.push({j, k});
else { //열쇠가 없으면 좌표 저장
ufkey[tmp-'A'].push_back({j, k});
map[j][k]='*';
}
}
}
}
map[j][k]='*';
}
}
}
scanf("%s", ks);
if(ks[0]) {
for(int i=0; ks[i]; i++) {
key[ks[i]-'a']=1;
while(!ufkey[ks[i]-'a'].empty()) {
q.push({ufkey[ks[i]-'a'].back().first, ufkey[ks[i]-'a'].back().second});
ufkey[ks[i]-'a'].pop_back();
}
}
}
while(!q.empty()) { //더 이상 길이 없을 때까지 탐색
int x = q.front().first, y = q.front().second;
q.pop();
//printf("%d %d\n", x, y);
LOOP(i, 4) {
int nx=x+xt[i], ny=y+yt[i];
switch(map[nx][ny]) {
case '\n':
case 0:
case '*': //막혀있음
continue;
case '$': //돈이 있음
cnt++;
case '.': //아직 탐색하지 않음
q.push({nx, ny}); //큐에 추가
break;
default: {
int tmp = map[nx][ny];
if(tmp>='a') { //열쇠는 추가
key[tmp-'a']=1;
while(!ufkey[tmp-'a'].empty()) {
q.push({ufkey[tmp-'a'].back().first, ufkey[tmp-'a'].back().second});
ufkey[tmp-'a'].pop_back();
}
q.push({nx, ny});
}
else { //문이
if(key[tmp-'A']) //열쇠가 있다면 열고 큐에 추가
q.push({nx, ny});
else //열쇠가 없으면 좌표 저장
ufkey[tmp-'A'].push_back({nx, ny});
}
}
}
map[nx][ny]='*';
}
}
LOOP(i, 30) ufkey[i-1].clear();
memset(key, 0, sizeof(int)*30);
cout << cnt << '\n';
}
return 0;
}
맨 처음에 짜다가 오류가 발생해서 덧 싀우고 덧 씌우다 보니 스파게티 코드가 되버렸다. ㅋㅋㅋㅋㅋ
<알고리즘>
1. 테두리 탐색하기.
2. 큐에서 하나씩 꺼내서 탐색하기
똑같은 방법으로 하는데 좋게 정리 된 코드가 있어서 가져왔다. (나는 귀찮)
<정리된 코드(풀어야 볼 수 있습니다.)>
https://www.acmicpc.net/source/20511286
로그인
www.acmicpc.net
※현재 고등학교 등교중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 10942번 팰린드롬? - DP (0) | 2022.09.28 |
---|---|
[C++] 9466번 텀 프로젝트 - DFS, 위상 정렬, union-find (0) | 2022.09.28 |
[C++] 9252번 LCS 2 - DP (0) | 2022.09.27 |
[C++] 7579 앱 - DP, 배낭 문제 (0) | 2022.09.27 |
[C++] 2623번 음악프로그램 - 위상 정렬 (0) | 2022.09.27 |
Comments