[3190]ヘビ


[3190]ヘビ

🔍 問題の説明


「Dummy」というドスゲームがありました.このゲームには蛇が這い出していて、りんごを食べると蛇の長さが増えます.ヘビが這い回って、壁や自分の体にぶつかって、ゲームは終わりました.
ゲームはNxN正方形の碁盤で行われ、一部の格にはりんごが置かれている.板の上下左右端に壁があります.ゲーム開始時、ヘビは一番上の一番左側にあり、ヘビの長さは1です.蛇は最初は右です.
ヘビは毎秒移動し、次のルールに従います.
* 먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
* 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
* 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.
リンゴの位置と蛇の移動経路を与えると,このゲームは数秒で終了する.
>入力
첫째 줄에 보드의 크기 N이 주어진다. (2 ≤ N ≤ 100) 다음 줄에 사과의 개수 K가 주어진다. (0 ≤ K ≤ 100)

다음 K개의 줄에는 사과의 위치가 주어지는데, 첫 번째 정수는 행, 두 번째 정수는 열 위치를 의미한다. 사과의 위치는 모두 다르며, 맨 위 맨 좌측 (1행 1열) 에는 사과가 없다.

다음 줄에는 뱀의 방향 변환 횟수 L 이 주어진다. (1 ≤ L ≤ 100)

다음 L개의 줄에는 뱀의 방향 변환 정보가 주어지는데,  정수 X와 문자 C로 이루어져 있으며. 게임 시작 시간으로부터 X초가 끝난 뒤에 왼쪽(C가 'L') 또는 오른쪽(C가 'D')로 90도 방향을 회전시킨다는 뜻이다. X는 10,000 이하의 양의 정수이며, 방향 전환 정보는 X가 증가하는 순으로 주어진다.
>出力
첫째 줄에 게임이 몇 초에 끝나는지 출력한다.

▼▼▼トラブルシューティング方法



📃 コード#コード#


[2021.03.24]

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int n, k, l, map[105][105];
queue<pair<int, char>> dir;
//*****************************************
//벽 또는 자기자신의 몸과 부딪히면 게임오버
//사과를 먹으면 몸 길이 증가
//*****************************************
int main() {
	scanf("%d", &n);		//맵 생성(n * n의 정사각형)
	scanf("%d", &k);		//사과 위치('A')
	for (int i = 0; i < k; i++) {
		int col, row;
		scanf("%d %d", &col, &row);
		map[col][row] = 'A';	
	}
	scanf("%d", &l);		//방향정보: dir = { 시간, 방향 } D : 오른쪽/ L : 왼쪽
	for (int i = 0; i < l; i++) {
		int sec; char d;
		scanf("%d %c", &sec, &d);
		dir.push({ sec, d });
	}dir.push({ 10005, 'D' });

	int way[2] = { 0, 1 };		//앞으로 갈 방향
	int x, y, nx, ny, time = 0;	//현재위치: (y, x) -> 옮길위치(ny, nx), 현재시간: time

	deque<pair<int, int>> s;	//뱀
	s.push_back({ 1, 1 });		//시작위치: (1, 1)
	
	while (!dir.empty()) {
		pair<int, char> d = dir.front();

		for (int i = time; i < d.first; i++) {
			x = s.front().second, y = s.front().first;
			nx = x + way[1], ny = y + way[0];

			map[y][x] = 'x';		//뱀이 있는 곳
			
			if (nx < 1 || nx > n || ny < 1 || ny > n || map[ny][nx] == 'x') {	//벽에 닿았거나 자신의 몸에 닿았을 때
				printf("%d", time + 1);
				return 0;
			}
			s.push_front({ ny, nx });	//(ny, nx)로 옮길 수 있으므로 이동
			
			if (map[ny][nx] != 'A') {	//옮긴 위치에 사과가 없는 경우 -> 뱀의 맨 뒷부분을 지워줌(뱀의 길이 유지)
				map[s.back().first][s.back().second] = ' ';
				s.pop_back();
			}
			time++;				//1초 증가
		}
		int tmp = way[0];			//방향전환
		if (way[0] == 0) {
			if (d.second == 'D')	{ way[0] = way[1];		way[1] = tmp; } 
			else			{ way[0] = -1 * way[1]; way[1] = tmp; }
		} 
		else {
			if (d.second == 'D')	{ way[0] = way[1]; way[1] = -1 * tmp; } 
			else			{ way[0] = way[1]; way[1] = tmp; }
		}
		dir.pop();
	}
	printf("%d", time);
}