거의 알고리즘 일기장

백준 3190번 _ 뱀 본문

알고리즘 문제풀이

백준 3190번 _ 뱀

건우권 2020. 4. 19. 18:07

https://www.acmicpc.net/problem/3190

 

3190번: 뱀

문제  'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임은 NxN 정사각 보드위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있다. 보드의 상하좌우 끝에 벽이 있다. 게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다. 뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따

www.acmicpc.net

풀이방법

이 문제는 자료형만 적절히 선언한다면 매우 직관적이고 풀기 쉬운 문제다.

 

나는 밑과 같이 자료형을 선언하였다.

queue<pair<int, int>> snake;	//뱀의 이동경로 저장과 삭제를 용이하기 위해서 que로 선언
set<pair<int, int>> snakeBody;	//자기 자신과 부딪쳤는지 확인을 용이하기 위한 set
map<int, char> changeTime;		//이동 경로가 언제바뀌는지 알수있게 해주는 map
int board[102][102];		
int N, K, L;			
int dy[] = {0, 0, -1, 1, 0 };	// 우 (1), 상 (2), 하(3), 좌(4) 
int dx[] = {0, 1, 0, 0, -1 };

전체코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <map>

using namespace std;

queue<pair<int, int>> snake;
set<pair<int, int>> snakeBody;
map<int, char> changeTime;
int board[102][102];
int N, K, L;
int dy[] = {0, 0, -1, 1, 0 };
int dx[] = {0, 1, 0, 0, -1 };

void Input()
{
	cin >> N;
	cin >> K;
	int y, x;
	for (int i = 0; i < K; i++)
	{
		cin >> y >> x;
		board[y][x] = 1;
	}
	cin >> L;
	int time;
	char turnDir;
	for (int i = 0; i < L; i++)
	{
		cin >> time >> turnDir;
		changeTime[time] = turnDir;
	}
}

int changeDirection(int dir, char turn)
{
	if (dir == 1)
	{
		if (turn == 'L')
			return 2;
		else
			return 3;
	}
	else if (dir == 2)
	{
		if (turn == 'L')
			return 4;
		else
			return 1;
	}
	else if (dir == 3)
	{
		if (turn == 'L')
			return 1;
		else
			return 4;
	}
	else if (dir == 4)
	{
		if (turn == 'L')
			return 3;
		else
			return 2;
	}
}

int game()
{
	snake.push({ 1,1 });
	snakeBody.insert({ 1, 1 });
	int dir = 1;
	int time = 0;
	int y= 1, x = 1;
	while (1)
	{
		time++;
		//뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
		int ny = y + dy[dir];
		int nx = x + dx[dir];

		//범위를 넘거나 자기자신에게 부딪혔는지 확인
		if ((ny >= 1 && nx >= 1 && ny <= N && nx <= N) == false)
			break;
		if (snakeBody.count({ ny, nx }) > 0)
			break;

		snake.push({ ny, nx });
		snakeBody.insert({ ny, nx });

		//이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다.
		if (board[ny][nx] == 0)
		{
			auto erasePos = snake.front();
			snake.pop();
			snakeBody.erase(snakeBody.find(erasePos));
		}
		else
			board[ny][nx] = 0;

		//방향이 변하는지 확인하고 
		if (changeTime.count(time) > 0)
		{
			dir = changeDirection(dir, changeTime[time]);
		}
		y = ny;
		x = nx;
	}
	return time;
}

int main()
{
	Input();
	cout << game();
	return 0;
}

후기

내 개인적으로는 삼성 기출문제중에서는 제일 쉬운 문제인것 같다.

반응형

'알고리즘 문제풀이' 카테고리의 다른 글

알고스팟_ 게임판 덮기  (0) 2020.04.21
알고스팟__소풍  (0) 2020.04.20
백준 12100번 _2048(Easy)  (0) 2020.04.19
백준 13460번 _ 구슬 탈출 2  (0) 2020.04.18
백준 17825번 _ 주사위 윷놀이  (0) 2020.04.17
Comments