문제 링크
https://www.acmicpc.net/problem/23031
문제
밤이 되면 어두워지는 다솔관에는 좀비가 나온다는 괴담이 있다. 그 좀비들의 정체는 바로 시험 기간에 공부하느라 지친 학생들이었다. 지친 학생들은 멀리서 보면 흡사 좀비이므로 학생 좀비라고 부르자. 아리는 낮에 공부하다가 깜빡하고 책을 두고 와서 밤에 다시 다솔관 4층으로 가야 한다. 밤에 다솔관 4층에 도착한 아리는 겁이 많아서 학생 좀비들을 마주친다면 기절해버리고 말 것이다. 아리는 기절 하지 않고 무사히 책을 찾아 돌아가고 싶다.
N × N으로 이루어진 다솔관 4층 곳곳에는 형광등 스위치와 학생 좀비들이 있다. 아리는 가장 왼쪽 위인 (1, 1)에서 출발하고 아리와 학생 좀비들은 모두 아래 방향을 보고 있다. 아리는 주어진 순서 A에 따라 이동을 한다. 문자열 A는 F, L, R로 구성되어 있으며, F는 앞으로 1칸 전진, L은 아리가 현재 바라보고 있는 방향을 기준으로 왼쪽으로 90도 방향 전환, R은 오른쪽으로 90도 방향을 전환한다. 다솔관 4층 주변에는 벽이 있어서 N × N 밖으로는 이동할 수 없다. 벽에 부딪히게 되면 전진하지 못하고 제자리에 머문다.
밤에는 학생들이 별로 없어서, 다솔관 4층은 암전 상태이다. 겁이 많은 아리는 형광등 스위치가 있는 칸에 도착하면 그 곳에 학생 좀비가 있더라도 학생 좀비랑 마주치기 전에 스위치를 켠다. 스위치를 켜게 되면 해당 스위치가 있는 칸과 상, 하, 좌, 우, 대각선 네 방향으로 1칸씩 불을 밝힌다. 스위치는 한 번 켜게 되면 꺼지지 않는다. 아리가 이동을 마칠 때마다 학생 좀비들은 자신이 보고 있는 방향으로 한 칸 전진한다. 만약 학생 좀비들이 벽에 부딪히게 되면 제자리에서 뒤를 돌아 반대 방향을 바라본다.
아리는 불이 꺼져있는 칸에서 학생 좀비와 함께 있으면 괴담에서 나오는 좀비로 착각하여 그 자리에서 바로 기절해 다음 날 아침에 깨어난다. 하지만 불이 켜져 있는 칸이거나 스위치가 있는 칸에서는 평범한 학생인 것을 알아보고 기절하지 않는다.
아리는 어두워진 다솔관에서 사물함을 찾아 이동하는 중이다. 이동 중에 기절하지 않을 수 있는지 구하여라.
입력
첫째 줄에 한 개의 정수 N(10 ≤ N ≤ 15)이 주어진다.
다음 줄에는 아리가 이동할 순서 문자열 A(10 ≤ A의 길이 ≤ 50)가 주어진다.
다음 줄부터 N × N의 다솔관 지도가 주어진다. 'Z'는 학생 좀비(0 ≤ 학생 좀비의 수 ≤ N × 2)를 나타내고 'S'는 형광등 스위치(0 ≤ 형광등 스위치의 수 ≤ N × 2)를 나타낸다. 'O'는 아무것도 없는 빈칸이다. 아리가 처음에 위치한 (1, 1)은 항상 빈칸인 경우만 입력으로 주어진다.
출력
아리가 기절을 하게 된다면 "Aaaaaah!"를 출력하고, 기절을 하지 않는다면 "Phew..."를 출력하시오.
예제 입력 1
11
FFFFFFRLRL
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
SOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
ZOOOOOOOOOO
예제 출력 1
Phew...
예제 입력 2
11
FFFFFFRLRL
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
ZOOOOOOOOOO
예제 출력 2
Aaaaaah!
알고리즘 분류
- 구현
풀이
시키는 대로 구현만 하면 되는데, 한 가지 고려해야할 것은 아리가 움직인 후 학생 좀비들이 움직이고 난 다음에도 아리가 학생 좀비와 어두운 칸에서 만나는 지 확인해야 한다는 것이다. 본인은 이거 고려 안 해서 시간 엄청 날렸음.
코드
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#define FASTIO cin.tie(0); cout.tie(0);
#define MAX 16
using namespace std;
struct Zombie {
int Y, X, Dir;
};
int N;
string A;
int Dir = 0;
pair<int, int> Pos;
int MoveY[4] = { 1, 0, -1, 0 };
int MoveX[4] = { 0, -1, 0, 1 };
int MAP[MAX][MAX];
vector<Zombie> Zombies;
bool Where_Light[MAX][MAX];
bool Enlightened[MAX][MAX];
bool Answer = false;
void input() {
cin >> N;
cin >> A;
for (int i = 0; i < N; i++) {
string S;
cin >> S;
for (int j = 0; j < S.size(); j++) {
if (S[j] == 'S') {
Where_Light[i][j] = true;
}
else if (S[j] == 'Z') {
Zombies.push_back({ i,j,0 });
MAP[i][j] = 1;
}
}
}
}
void enlighten(int Y, int X) {
Enlightened[Y - 1][X - 1] = true;
Enlightened[Y - 1][X] = true;
Enlightened[Y - 1][X + 1] = true;
Enlightened[Y][X - 1] = true;
Enlightened[Y][X] = true;
Enlightened[Y][X + 1] = true;
Enlightened[Y + 1][X - 1] = true;
Enlightened[Y + 1][X] = true;
Enlightened[Y + 1][X + 1] = true;
}
void zombie_Move() {
for (int i = 0; i < Zombies.size(); i++) {
int NextY = Zombies[i].Y + MoveY[Zombies[i].Dir];
int NextX = Zombies[i].X + MoveX[Zombies[i].Dir];
if ((NextY < 0) || (NextY >= N) || (NextX < 0) || (NextX >= N)) {
if (Zombies[i].Dir == 0) {
Zombies[i].Dir = 2;
}
else {
Zombies[i].Dir = 0;
}
continue;
}
Zombies[i].Y = NextY;
Zombies[i].X = NextX;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
MAP[i][j] = 0;
}
}
for (int i = 0; i < Zombies.size(); i++) {
int CurY = Zombies[i].Y;
int CurX = Zombies[i].X;
MAP[CurY][CurX] = 1;
}
}
void settings() {
Pos = make_pair(0, 0);
for (int i = 0; i < A.size(); i++) {
char Cmd = A[i];
if (Cmd == 'F') {
int NextY = Pos.first + MoveY[Dir];
int NextX = Pos.second + MoveX[Dir];
if ((NextY >= 0) && (NextY < N) && (NextX >= 0) && (NextX < N)) {
Pos = make_pair(NextY, NextX);
if (Where_Light[Pos.first][Pos.second]) {
enlighten(Pos.first, Pos.second);
}
if (MAP[Pos.first][Pos.second] == 1) {
if ((!Enlightened[Pos.first][Pos.second]) && (!Where_Light[Pos.first][Pos.second])) {
Answer = true;
}
}
}
}
else if (Cmd == 'L') {
Dir--;
if (Dir < 0) {
Dir = 3;
}
}
else if (Cmd == 'R') {
Dir++;
if (Dir > 3) {
Dir = 0;
}
}
zombie_Move();
if (MAP[Pos.first][Pos.second] == 1) {
if ((!Enlightened[Pos.first][Pos.second]) && (MAP[Pos.first][Pos.second] != 2)) {
Answer = true;
}
}
}
}
void find_Answer() {
if (Answer) {
cout << "Aaaaaah!\n";
}
else {
cout << "Phew...\n";
}
}
int main() {
FASTIO
input();
settings();
find_Answer();
return 0;
}
'BOJ > Gold' 카테고리의 다른 글
[BOJ/Gold 3] 백준 25240 가희와 파일 탐색기 2(C++) (0) | 2022.10.07 |
---|---|
[BOJ/Gold 4] 백준 23294 웹 브라우저 1(C++) (0) | 2022.10.07 |
[BOJ/Gold 5] 백준 25294 달팽이와 쿼리(C++) (0) | 2022.10.06 |
[BOJ/Gold 4] 백준 2487 섞기 수열(C++) (0) | 2022.06.09 |
[BOJ/Gold 5] 백준 1684 같은 나머지(C++) (0) | 2022.06.09 |