2차원 배열 내에서의 뱀의 움직임을 시뮬레이션 하세요!
뱀은 방향을 갖습니다. 방향 커맨드는 이동 후 초가 지나면 받습니다(의역)
게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다.
뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.
뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.
그냥 규칙을 구현하면서 시뮬레이션을 해줬다.
(0초) ---이동---- 1초 끝 직전에 방향커맨드(1초)
문제 상 게임 시작 시간으로부터 X초가 끝난 뒤에 커맨드가 들어온 거라고 해서
이렇게 구현을 했다.
사실 나의 착각?? 땜에 헷갈렸던 부분이다. 나도 말로 하려니 이상한데 충돌이라 하면 벽에 수직한 방향으로 벽 바로 앞에 멈춰섰을 때(.....)라고 생각했다. 벽이랑 같은 방향으로 벽 코앞에서 뱀이 흘러가는 건 괜찮고.. ㅋㅋㅋㅋㅋㅋ...먼가 뱀이 이동방향쪽으로 충격파를 쏜다고 착각한 거 같다;;;
나랑 비슷한 착각을 한 사람은 없겠지만..
당연히 후자다. 머리 한칸 앞으로 -> 사과 검사-> 사과 없으면 줄어듦
과정에서 사과검사 할 때 꼬리와 충돌한 것도 충돌이 맞다고 생각했다.
전자로 구현했을 땐 문제의 3번 테케에서 틀렸었다.
사과를 먹으면 사과가 없어져야하는데 그걸 빼먹고 사과 없으면 몸이 줄어듦만 구현했다..
#include<iostream>
#include<list>
#include<queue>
#include<memory.h>
using namespace std;
//뱀을 리스트로 표현 -> 사과먹을 때 / 못먹었을 때 추가가 용이하다
//움직일 때는 그냥 안에 내용물을 그대로 둬도 됨
struct pos {
int i, j;
};
struct com {
int x;
char c;
};
int n;
bool tab[101][101];
int di[] = { -1,0,1,0 };
int dj[] = { 0,1,0,-1 };
int update_d(int d, char c) {
if (c == 'L') {
return ((d - 1) + 4) % 4;
}
else {
return (d + 1) % 4;
}
}
bool is_col_me(list<pos>& snake) {
pos head = snake.front();
for (list<pos>::iterator it = ++snake.begin(); it != snake.end(); it++) {
if (it->i == head.i && it->j == head.j) {
return true;
}
}
return false;
}
bool is_col_wall(pos new_head) {
if (new_head.i >= 1 && new_head.i <= n && new_head.j >= 1 && new_head.j <= n) {
return false;
}
return true;
}
/*
void print_snake(list<pos>& snake, int d) {
int marking[101][101];
memset(marking, 0, sizeof(marking));
cout << "dir : " << d << endl;
int ctr = 1;
for (list<pos>::iterator it = snake.begin(); it != snake.end(); it++) {
cout << "(" << it->i << "," << it->j << ")\t";
marking[it->i][it->j] = ctr++;
}
cout << endl << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << marking[i][j] << " ";
}
cout << endl;
}
cout << endl << endl << endl;
}
*/
int main() {
int k;
cin >> n>>k;
memset(tab, 0, sizeof(tab));
for (int ctr = 0; ctr < k; ctr++) {
int i, j;
cin >> i >> j;
tab[i][j] = true;
}
int l;
cin >> l;
queue<com> commands;
for (int i = 0; i < l; i++) {
int x;
char c;
cin >> x >> c;
commands.push(com{ x,c });
}
int time = 0;
list<pos> snake;
int d=1;//오른쪽
snake.push_front(pos{ 1,1 });
//cout << "처음 조건 : " << !is_col_me(snake) <<","<< !is_col_wall(snake.front()) <<","<< (time <= 10000) << endl;
//시간이 다 되는 경우에 대해선 명시 안돼잇음
while (true) {
pos head = snake.front();
pos new_head = pos{head.i+di[d],head.j+dj[d]};
snake.push_front(new_head);
//초가 지남
time++;
if (is_col_wall(snake.front()) || is_col_me(snake)) {
break;
}
if (tab[new_head.i][new_head.j] == false) {//사과 없으면 줄어듦
snake.pop_back();
}
else {//사과를 먹으면 없어지는 거 빠트림
tab[new_head.i][new_head.j] = false;
}
//방향 커맨드를 받음
if (!commands.empty()) {
com cur = commands.front();
if (cur.x == time) {
commands.pop();
d = update_d(d,cur.c);
}
}
//cout << "cur time :" << time << endl;
//print_snake(snake, d);
}
cout << time << endl;
}