리뷰
https://www.acmicpc.net/problem/23747
맵이 두개인 이세계 대환장 문제, 메타버스 느낌이 들어 재밌었다.
전역 변수
- n, m : 맵의 세로/가로 길이를 저장할 변수
- sx, sy : 초기 위치에서 이세계의 이동 좌표를 저장할 변수
- lst : 이세계 맵 정보를 저장할 배열
- orders : 한별이의 여행 기록을 저장할 변수
- ans : 현실세계 맵 정보를 저장할 배열
- v : 방문 정보를 저장할 배열
- dx, dy : 4방향 탐색을 위한 방향 배열
- Pos : 플러드 필을 할 때 위치 정보 x, y를 정의할 구조체
함수
1. floodfill
void floodfill()
플러드 필을 통해 같은 그룹의 시야를 밝히기 위한 함수
- Pos타입의 큐 q를 초기화 하고, 현재 위치 sx, sy를 push해준다.
- ans의 sx, sy에 '.'를, v의 sx, sy에 방문 처리를 진행해 준다.
- q가 빌 때 까지 while 루프를 순회하고, 매 루프마다 요소를 한개씩 꺼내어 준다.
- 현재 위치에서 4방향 탐색을 진행하고, 맵의 범위 안이면서 같은 그룹에 속하고, 방문하지 않았다면 이동을 진행한다.
- 이동 후엔 방문처리 및, ans에 '.'로 기록해 주고, q에 이동한 위치를 삽입해 준다.
문제풀이
- n, m값을 입력 받고, n * m크기의 맵을 입력 받으면서 ans는 모두 '#'으로 초기화 해준다.
- sx, sy, orders를 입력 받고, 0-based-indexing을 위해 sx, sy를 각각 1만큼 줄여준다.
- 변수 idx를 -1로 초기화 하고, idx를 전위증가한 값이 orders.size()보다 작을 때 까지 while루프를 돌려준다.
- 매 루프마다 변수 op에 orders의 idx값을 받아 여행 기록에 맞게 로직을 진행해 준다.
- op가 'U'라면 sx를 1만큼 빼내어 준다.
- op가 'D'라면 sx를 1만큼 더해 준다.
- op가 'L'라면 sy를 1만큼 빼내어 준다.
- op가 'R'라면 sy를 1만큼 더해 준다.
- op가 'W'라면 floodfill 함수를 호출해 준다.
- while루프가 종료되었다면 현재 sx, sy위치와 4방향의 ans값을 모두 '.'로 변경해 준다.
- ans에 저장된 값을 n * m크기만큼 출력해 준다.
트러블 슈팅
없음
참고 사항
- 여행 기록에서 한별이가 격자를 벗어나는 경우는 주어지지 않는다.
- 와드를 설치하지는 않았지만, 한별이의 최종 위치의 위, 아래, 왼쪽, 오른쪽 칸은 시야로 확보하고 있다.
- 지나온 경로를 모두 시야로 확보하지는 않는다.
정답 코드
#include<iostream>
#include<queue>
using namespace std;
int n, m, sx, sy;
string lst[1000], orders;
char ans[1000][1000];
bool v[1000][1000];
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
struct Pos {
int x, y;
};
void floodfill() {
queue<Pos> q;
q.push({ sx, sy });
ans[sx][sy] = '.';
v[sx][sy] = true;
while (!q.empty()) {
Pos pos = q.front(); q.pop();
int cx = pos.x, cy = pos.y;
for (int i = 0; i < 4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i];
if (0 <= nx && nx < n && 0 <= ny && ny < m && lst[nx][ny] == lst[sx][sy] && !v[nx][ny]) {
v[nx][ny] = true;
ans[nx][ny] = '.';
q.push({ nx, ny });
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; ++i) {
cin >> lst[i];
for (int j = 0; j < m; ++j) {
ans[i][j] = '#';
}
}
cin >> sx >> sy >> orders;
--sx, --sy;
int idx = -1;
while (++idx < orders.size()) {
const char& op = orders[idx];
if (op == 'U') sx -= 1;
else if (op == 'D') sx += 1;
else if (op == 'L') sy -= 1;
else if (op == 'R') sy += 1;
else floodfill();
}
ans[sx][sy] = '.';
for (int i = 0; i < 4; ++i) {
int nx = sx + dx[i], ny = sy + dy[i];
if (0 <= nx && nx < n && 0 <= ny && ny < m) ans[nx][ny] = '.';
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << ans[i][j];
}
cout << "\n";
}
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G5] 백준 1038번 감소하는 수 C++ 구현 (0) | 2025.03.11 |
---|---|
[G5] 백준 2096번 내려가기 C++ 다이나믹 프로그래밍 (0) | 2025.03.10 |
[G3] 백준 1941번 소문난 칠공주 C++ 백트래킹, 너비 우선 탐색 (0) | 2025.03.08 |
[G3] 백준 23084번 IUPC와 비밀번호 C++ 문자열, 슬라이딩 윈도우 (0) | 2025.03.08 |
[G4] 백준 30827번 회의실 배정 C++ 정렬, 멀티셋, 그리디 알고리즘 (0) | 2025.03.08 |