본문 바로가기

코딩/알고리즘

SW expert academy 1824 혁진이의 프로그램 검증



기본적인 풀이는 DFS이다.


DP[i][j][memory][direct]는 

"i, j의 위치에서 memory의 값을 메모리에 저장해놨을 때, direct로 프로그램이 진행되고 있는 상황에서의 프로그램이 끝날 수 있는 지의 여부"

이다.

그 결과값이 1이면 끝날 수 있고, 2이면 끝날 수 없음을 의미한다.


혁진이의 프로그램이 무한루프가 돈다는 것은, 같은 memory와 direct의 상황에서 같은 i,j를 방문했다는 것으로 체크하면 된다.


#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <string.h>
#include <utility>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <math.h>
#include <string>
#include <sstream>

using namespace std;


int T;
int R, C;

char arr[21][21];

int memo[21][21][16][4];
int tt[4][3] = { {0,-1, 0}, {-1, 0, 1} , {0, 1, 2}, {1, 0, 3} };

int dfs(int nowi, int nowj, int memory, int direct) { // 0, 1, 2, 3 왼 위 우 하
	int& m = memo[nowi][nowj][memory][direct];

	if (m == 1 || m == 2) return m;
	if (m == -1) {
		m = 2;
		return 2;
	}
	m = -1;

	if (arr[nowi][nowj] <= '9' && arr[nowi][nowj] >= '0') {
		memory = arr[nowi][nowj] - '0';

		int nexti = nowi + tt[direct][0];
		int nextj = nowj + tt[direct][1];

		if (nexti >= R) nexti = 0;
		else if (nexti < 0) nexti = R - 1;

		if (nextj >= C) nextj = 0;
		else if (nextj < 0) nextj = C - 1;

		m = dfs(nexti, nextj, memory, direct);
	}
	else {
		int nexti, nextj;
		int nextDirect = 0;
		bool flag = false;
		switch (arr[nowi][nowj]) {
		case '?':
			for (auto t : tt) {
				nexti = nowi + t[0];
				nextj = nowj + t[1];

				if (nexti >= R) nexti = 0;
				else if (nexti < 0) nexti = R - 1;

				if (nextj >= C) nextj = 0;
				else if (nextj < 0) nextj = C - 1;

				int& nextm = memo[nexti][nextj][memory][t[2]];
				if (dfs(nexti, nextj, memory, t[2]) == 1) {
					m = 1;
					flag = true;
					break;
				}
			}
			if (flag == false) {
				m = 2;
			}
			break;
		case '@':
			m = 1;
			break;
		case '<':
			nextj = nowj - 1;
			if (nextj < 0) nextj = C - 1;
			m = dfs(nowi, nextj, memory, 0);
			break;
		case '^':
			nexti = nowi - 1;
			if (nexti < 0) nexti = R - 1;
			m = dfs(nexti, nowj, memory, 1);
			break;
		case '>':
			nextj = nowj + 1;
			if (nextj >= C) nextj = 0;
			m = dfs(nowi, nextj, memory, 2);
			break;
		case 'v':
			nexti = nowi + 1;
			if (nexti >= R) nexti = 0;
			m = dfs(nexti, nowj, memory, 3);
			break;
		case '|':
			if (memory == 0) {
				nextDirect = 3;
				nexti = nowi + 1;
				if (nexti >= R) nexti = 0;
			}
			else {
				nextDirect = 1;
				nexti = nowi - 1;
				if (nexti < 0) nexti = R - 1;
			}
			m = dfs(nexti, nowj, memory, nextDirect);
			break;
		case '_':
			if (memory == 0) {
				nextDirect = 2;
				nextj = nowj + 1;
				if (nextj >= C) nextj = 0;
			}
			else {
				nextDirect = 0;
				nextj = nowj - 1;
				if (nextj < 0) nextj = C - 1;
			}
			m = dfs(nowi, nextj, memory, nextDirect);
			break;
		case '+':
			memory++;
			if (memory >= 16) memory = 0;

			nexti = nowi + tt[direct][0];
			nextj = nowj + tt[direct][1];

			if (nexti >= R) nexti = 0;
			else if (nexti < 0) nexti = R - 1;

			if (nextj >= C) nextj = 0;
			else if (nextj < 0) nextj = C - 1;

			m = dfs(nexti, nextj, memory, direct);
			break;
		case '-':
			memory--;
			if (memory < 0) memory = 15;

			nexti = nowi + tt[direct][0];
			nextj = nowj + tt[direct][1];

			if (nexti >= R) nexti = 0;
			else if (nexti < 0) nexti = R - 1;

			if (nextj >= C) nextj = 0;
			else if (nextj < 0) nextj = C - 1;

			m = dfs(nexti, nextj, memory, direct);
			break;
		case '.':
			nexti = nowi + tt[direct][0];
			nextj = nowj + tt[direct][1];

			if (nexti >= R) nexti = 0;
			else if (nexti < 0) nexti = R - 1;

			if (nextj >= C) nextj = 0;
			else if (nextj < 0) nextj = C - 1;

			m = dfs(nexti, nextj, memory, direct);
			break;

		}
	}

	return m;
}

int main() {
	scanf("%d", &T);

	for (int tc = 1; tc <= T; tc++) {

		for (int i = 0; i < 21; i++) {
			for (int j = 0; j < 21; j++) {
				arr[i][j] = 'A';
				for (int a1 = 0; a1 < 16; a1++) {
					for (int a2 = 0; a2 < 4; a2++) {
						memo[i][j][a1][a2] = 0;
					}
				}
			}
		}


		scanf("%d %d", &R, &C);

		string tempstr;

		bool noalpha = true;

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

			cin >> tempstr;

			for (int j = 0; j < C; j++) {
				arr[i][j] = tempstr[j];
				if (arr[i][j] == '@') {
					noalpha = false;
				}
			}
		}
		int result = -1;
		if (!noalpha) result = dfs(0, 0, 0, 2);


		string res = (result == 1) ? "YES" : "NO";

		cout << "#" << tc << " " << res << endl;
	}

	return 0;
}








'코딩 > 알고리즘' 카테고리의 다른 글

SW expert academy 1238 Contact  (0) 2019.04.13
SW expert academy 1227 미로2  (0) 2019.04.13
SW expert academy 1251 하나로  (0) 2019.04.13
백준 17069 파이프 옮기기2, 17070 파이프 옮기기1  (0) 2019.04.13
백준 1315 RPG  (0) 2018.06.03