3190번. 뱀

b4failrise ㅣ 2019. 4. 13. 19:15

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int N, K, L;
int map[102][102];	// 1, 1부터 N, N까지 주의
int vis[102][102];
vector<pair<int, char>> infor;
int dr[4] = { -1, 0, 1, 0 };	//방향 정보 0:북 1: 동 2: 남 3: 서
int dc[4] = { 0, 1, 0, -1 };
bool fin;	//벽 부딪혔는 지 체크
int state = 1;					//방향 정보 0:북 1: 동 2: 남 3: 서
int cnt;	//초
int idx;	//방향 변환 정보 인덱스
int len = 1;
queue < pair<int, int>> tail;	//발자취 정보 : front가 꼬리
void dfs(int r, int c) {
	if (idx < L) {		// idx를 지속적으로 높이면 아래 배열 참조할 때 참조에러
		if (cnt == infor[idx].first) {
			if (infor[idx].second == 'L') {
				state = (state - 1) % 4;	// -1 % 4 = -1  (3을 의도)
				if (state < 0)				//음수일 때, 따로 처리
					state += 4;
			}
			
			else if(infor[idx].second == 'D')
				state = (state + 1) % 4;
			idx++;
		}
	}

	int nr = r + dr[state];
	int nc = c + dc[state];
	if (nr <= 0 || nc <= 0 || nr > N || nc > N || vis[nr][nc]) {	//벽 부딪치거나 자기 몸에 닿을 때
		fin = true;
		cnt++;
		return;
	}
	if (map[nr][nc] == 1) { //사과 있으면
		vis[nr][nc] = 1;	//앞으로 전진
		map[nr][nc] = 0;	//사과 먹기
		tail.push({ nr, nc });	//발자취 추가
		cnt++;				//초 증가
		len++;				//몸 길이 증가
		dfs(nr, nc);
	}
	else {	//사과 없으면(독립적이므로 if, else)

		tail.push({ nr, nc });	//발자취 추가
		if (len < tail.size()) {	// 원래 길이보다 길어진다면
			vis[tail.front().first][tail.front().second] = 0;	//꼬리 없애기
			tail.pop();		// 벡터에서 삭제
		}
		vis[nr][nc] = 1;	//앞으로 전진
		cnt++;				//초 증가
		dfs(nr, nc);
	}
}
int main() {
	cin >> N >> K;
	int a, b;
	for (int i = 0; i < K; i++) {
		cin >> a >> b;
		map[a][b] = 1;	//사과 위치
	}
	cin >> L;
	char c;
	for (int i = 0; i < L; i++) {
		cin >> a >> c;
		infor.push_back({ a, c });	// 방향 변환 정보
	}
	tail.push({ 1,1 });
	vis[1][1] = 1;
	dfs(1, 1);
	cout << cnt << endl;

}

1. 방향 변환 정보의 X는 누적된 시간

  - 초를 세면서 방향 변환 정보에서 현재 idx가 가리키는 X값과 같아지면 state를 변경

  - ※ idx 계속 더하면 if문에서 지속적으로 조건 확인하기 때문에 벡터 크기를 초과한 셀을 방문 하면 에러가 발생

 

2. 4 방향을 탐색하는 게 아니라, 상태 유지를 하면서 전진해야 함 (state변수 이용)

  - 90도 방향 전환은 +,- 와 %로 가능 (단, %가 음수를 처리하지 못하므로 음수일 땐 더하기 처리해주어야 함)

 

3. 발자취 추적은 queue 하나로 가능

  - 나아가면서 추가하고 길이 유지하면서 front로 꼬리를 자를 수 있음