728x90
시뮬레이션 문제를 풀 땐, 문제에 나와있는 조건대로 잘 따라 풀어주어야 한다.
뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.
0. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.
1. 먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
2. 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
3. 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.
우선,
만약 벽 또는 자기자신의 몸과 만난다면? break하고 게임을 종료시키면 된다.
그 다음엔 사과가 있는 경우와 없는 경우로 나누어 조건식을 세운 다음 문제를 풀면 된다.
방향 전환이 조금 까다로운데, 문제 처음에서는 무조건 오른쪽으로 이동한다고 하였으므로 오른쪽 direction을 0으로 설정하고 마찬가지로 dx[0]과 dy[0]도 오른쪽으로 향하게 해준다.
그 후 여느 시뮬레이션 문제와 마찬가지로 방향 벡터를 이용하면 된다
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
int N, K, L;
int MAP[101][101];
// 오른, 왼, 아래, 위
int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };
vector<pair<int, char>> V;
int Turn_Direction(int d, char c)
{
if (c == 'L')//왼쪽으로 회전할 때
{
if (d == 0) return 3; // 오른쪽으로 진행하고 있었으면, 위로 이동
else if (d == 1) return 2; // 왼쪽으로 진행하고 있었으면, 아래로 이동
else if (d == 2) return 0; // 아래로 진행하고 있었으면, 오른쪽으로 이동
else if (d == 3) return 1; // 위로 진행하고 있었으면, 왼쪽으로 이동
}
else if (c == 'D') // 오른쪽으로 회전할 때
{
if (d == 0) return 2; // 진행방향 오른쪽이면, 아래로 이동
else if (d == 1) return 3; // 진행방향 왼쪽이면, 위로 이동
else if (d == 2) return 1; // 진행방향 아래쪽이면, 왼쪽으로 이동
else if (d == 3) return 0; // 진행방향 위쪽이면, 오른쪽으로 이동
}
}
void Solution()
{
deque<pair<int, int>> Q;
int x = 0;
int y = 0;
int d = 0;
int Time = 0;
int Idx = 0;
Q.push_back(make_pair(x, y));
MAP[x][y] = 2;// start
while (1)
{
Time++; // 한번 이동할 때 마다 time ++
int nx = x + dx[d]; // 오른쪽 왼쪽 아래쪽 위쪽 순서로 이동
int ny = y + dy[d];
if ((nx < 0 || ny < 0 || nx >= N || ny >= N) || MAP[nx][ny] == 2) // 벽에 닿았거나 내 몸과 닿으면
{
break;
}
else if (MAP[nx][ny] == 0) // 사과 없으면
{
MAP[nx][ny] = 2; // 머리 전진
MAP[Q.back().first][Q.back().second] = 0; // 꼬리 전진
Q.pop_back(); // 꼬리 정보 삭제
Q.push_front(make_pair(nx, ny)); // 새로운 머리 정보 등록
}
else if (MAP[nx][ny] == 1) // 사과 있으면
{
MAP[nx][ny] = 2; // 머리 전진
Q.push_front(make_pair(nx, ny)); // 새로운 머리 정보 등록
}
if (Idx < V.size()) // 이동횟수보다 아직 덜 이동했으면
{
if (Time == V[Idx].first) // 만약 방향 바꿀 시간이 됐다면
{
if (V[Idx].second == 'L') d = Turn_Direction(d, 'L'); // 현재 d와 L을 보내 앞으로 갈 d를 정함
else if (V[Idx].second == 'D') d = Turn_Direction(d, 'D'); // 마찬가지
Idx++;
}
}
x = nx;
y = ny;
}
cout << Time << endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> K;
for (int i = 0; i < K; i++)
{
int x, y;
cin >> x >> y;
x = x - 1;
y = y - 1;
MAP[x][y] = 1; // 사과 = 1로 표시
}
cin >> L;
for (int i = 0; i < L; i++)
{
int a;
char b;
cin >> a >> b;
V.push_back(make_pair(a, b));
}
Solution();
return 0;
}
728x90
'알고리즘 > 백준(BOJ)' 카테고리의 다른 글
백준 1107번 리모컨 <브루트포스> (0) | 2022.07.12 |
---|---|
다익스트라 백준 1238번 파티 (0) | 2022.07.12 |
DP의 대표적 문제 - BOJ 1463번 (0) | 2022.07.12 |
[백준/C++] 9012번 괄호 (0) | 2022.07.12 |
[백준/C++] 10989번 수 정렬하기 - 3 (0) | 2022.07.12 |