본문 바로가기
Programming/Algorithm

백준 3190 뱀

by OKOK 2018. 2. 21.

/*

뱀 문제 

머리를 다음칸에 위치 시킵니다.

if 사과 있, 사과를 먹고 꼬리는 그대로

else 사과 없, 꼬리가 위치한 칸을 비웁니다.

뱀이 죽는데 몇 초가 걸리는지 확인해보세요.

*/


#include <iostream>

#include <vector>

#include <queue>

#define SIZE 101

using namespace std;

int n, k, l;

char c;

int x, y, nx, ny, d;

int dx[] = { 0,0,1,-1 };

int dy[] = { 1,-1,0,0 }; // 동서남북

int sec;

int a, b;

int map[SIZE][SIZE];

struct points {

int x;

int y;

};

queue<points> dir_info;

queue<points> snake;


void problemIn() {

cin >> n >> k; // 맵의 크기, 사과의 개수

for (int i = 0; i < k; i++) {

cin >> a >> b;

map[a-1][b-1] = 2; // 사과가 있으면 2로 표시합니다.

}

cin >> l; // 회전 개수

for (int i = 0; i < l; i++) {

cin >> x >> c;

if (c == 'D') y = 1; // right

else if (c == 'L') y = -1; //left

dir_info.push({ x,y });

}

}

/*

뱀이 위치한 곳은 벡터에 넣도록 하겠습니다. 넣고, 빼고를 반복합니다.

1을 만나면 break 를 해서 while 문을 벗어납니다.

*/

int turn_right(int dir) {

if (dir == 0) return 2;

else if (dir == 1) return 3;

else if (dir == 2) return 1;

else return 0;

}

int turn_left(int dir) {

if (dir == 0) return 3;

else if (dir == 1) return 2;

else if (dir == 2) return 0;

else return 1;

}


void solve() {

x = y = d = 0; // 처음 시작위치 맨왼쪽상단, 방향은 동쪽

while (1) {


snake.push({ x,y }); // 몸의 자기 위치를 넣습니다.

map[x][y] = 1; // map 에 뱀 표시


if (sec == dir_info.front().x) { // 초와 방향 정보에 대해서

if (dir_info.front().y == 1) { // 오른쪽으로 회전하려면 

d = turn_right(d);

}

else {

d = turn_left(d);

}

dir_info.pop();

}

nx = x + dx[d]; //이동을 하고 나서,

ny = y + dy[d];

if (nx >= 0 && ny >= 0 && nx < n && ny < n) {

if (map[nx][ny] == 0) { // 사과도, 벽도 아닌 0 (길) 이면

map[snake.front().x][snake.front().y] = 0;

x = nx;

y = ny;

snake.pop(); // 스네이크 큐에서 처음 들어온 값 지우기.

}

else if (map[nx][ny] == 2) { // 사과 이면

x = nx;

y = ny; // 지우기가 없습니다.

}

else if (map[nx][ny] == 1) { // 벽이나, 자신의 몸이면,

sec++;

break;

}

}

else {

sec++;

break;

}

sec++;

}

}


int main(void) {

problemIn();


solve();


cout << sec << endl;

return 0;


뱀의 표시를 해주는 것과, break 문에서 빠져나오는 곳을 잘 찾아야 합니다.