U E D R , A S I H C RSS

Robbery/조현태

�낀� � 설명

하루종� 루니아만 했다아아아..ㅠ.ㅜ 너무 게으른거아�?? �거 문제있는�.. '게으름 유전�' 가 들어있는건가..OTL..
... � 그래� ��� �기는것.. 게임좀 하면 어때~~~~ (미래� 니트족 한명 � 추가�겠군..;;)
.. 너무 놀았으니 �기전� 간단히 한개 풀어주고 �야지.. 해서 푼게 �것.
CSI를 많� �서 그런지 형사아저씨를 �고싶었나보다.^^

주어진 예제와 그 �외� 몇몇 사항� 바탕으로 테스트를 하였다.
경우� 수가 여러가지 나오는 경우를 어떻게 처리할까 고민했는�.. 못찾� 걸로 할까? 아니면 답으로 간주해서 출력할까? 하다가, � 경우는 못찾� 걸로 처리하였다. ( "Nothing known." 으로 출력�다. )
'명확한 경우' � �하지 않기때문�..^^
최�화를 아예 안할까 하다가.. 그럼 너무너무 간단해져서 약간�나마 최�화를 했다.

ìž�ì „ê±° 문제ì—� ì�´ 소스를 배껴넣다가.. 규칙ì�„ ì�¼ë€ 잘못 ì�´í•´í•œê²ƒ 같아서 수정했다.
�전� 경우 �둑� 특정시간� 존재할 수 없는경우 "The robber has escaped." 를 출력했으나, 지금� 모든 시간� 움�임� 고려해서 존재하지 않으면 "The robber has escaped."를 출력하�� 수정하였다. (사실 소스��선 그다지 바�건 없다..^^)

소스


~cpp
#include <iostream>
#include <Windows.h>
#include <vector>
#include <algorithm>
#include <atltypes.h>

using namespace std;

#define CAN_MOVE_POINT 0
#define DONT_MOVE_POINT 1

vector< vector< vector<int> > > g_cityMap;
vector< vector<POINT> > g_canMovePoints;
vector<int> g_saveMessageTime;
vector< vector<POINT> > g_maxPoints;

void InitCityMap(int cityWidth, int cityHeight, int keepTime)
{
	g_maxPoints.clear();
	g_saveMessageTime.clear();
	g_canMovePoints.clear();
	g_cityMap.clear();

	g_canMovePoints.resize(keepTime);
	g_cityMap.resize(keepTime);
	for (register int i = 0; i < (int)g_cityMap.size(); ++i)
	{
		g_cityMap[i].resize(cityWidth);
		for(register int j = 0; j < (int)g_cityMap[i].size(); ++j)
		{
			g_cityMap[i][j].resize(cityHeight);
		}
	}
}

void SetMessagePoints(int receiveTime, int left, int top, int right, int bottom)
{
	for (register int i = left - 1; i < right; ++i)
	{
		for (register int j = top - 1; j < bottom; ++j)
		{
			g_cityMap[receiveTime - 1][i][j] = DONT_MOVE_POINT;
		}
	}
}

void SetCanMovePoints()
{
	for (register int i = 0; i < (int)g_cityMap.size(); ++i)
	{
		for(register int j = 0; j < (int)g_cityMap[i].size(); ++j)
		{
			for(register int k = 0; k < (int)g_cityMap[i][j].size(); ++k)
			{
				if (CAN_MOVE_POINT == g_cityMap[i][j][k])
				{
					POINT canMovePoint;
					canMovePoint.x = j;
					canMovePoint.y = k;
					g_canMovePoints[i].push_back(canMovePoint);
				}
			}
		}
	}
}

void MoveNextPoint(POINT nowPoint, POINT targetPoint, int nowTime, int targetTime, vector<POINT>& movedPoint)
{
	//// ��할 수 없는 곳�때 ////
	if (0 > nowPoint.x || (int)g_cityMap[nowTime].size() <= nowPoint.x)
		return;
	if (0 > nowPoint.y || (int)g_cityMap[nowTime][nowPoint.x].size() <= nowPoint.y)
		return;
	if (DONT_MOVE_POINT == g_cityMap[nowTime][nowPoint.x][nowPoint.y])
		return;

	//// 목표시간� �착했�때 ////
	if (nowTime == targetTime)
	{
		//// 목표지�� 아�때 ////
		if (nowPoint.x != targetPoint.x || nowPoint.y != targetPoint.y)
			return;

		int suchTime = -1;
		for (register int i = 0; i < (int)g_saveMessageTime.size(); ++i)
		{
			if (nowTime < g_saveMessageTime[i])
			{
				suchTime = g_saveMessageTime[i];
			}
		}
		//// ��� 지령받� 지�� 없�때 ////
		if (-1 == suchTime)
		{
			movedPoint.push_back(nowPoint);
			g_maxPoints.push_back(movedPoint);
			movedPoint.pop_back();
			return;
		}

		//// 지령받� 지�� 있�때 ////
		for (register int i = 0; i < (int)g_canMovePoints[suchTime].size(); ++i)
		{
			MoveNextPoint(nowPoint, g_canMovePoints[suchTime][i], nowTime, suchTime, movedPoint);
		}
		return;
	}

	//// 움��는 중�때 ////
	int movingTimeX = targetPoint.x - nowPoint.x;
	int movingTimeY = targetPoint.y - nowPoint.y;
	if (abs(movingTimeX) + abs(movingTimeY) > targetTime - nowTime)
		return;
	else
	{
		movedPoint.push_back(nowPoint);
		POINT tempPoint = nowPoint;
		if (0 < movingTimeX)
		{
			++nowPoint.x;
			MoveNextPoint(nowPoint, targetPoint, nowTime + 1, targetTime, movedPoint);
		}
		else if (0 > movingTimeX)
		{
			--nowPoint.x;
			MoveNextPoint(nowPoint, targetPoint, nowTime + 1, targetTime, movedPoint);
		}
		nowPoint = tempPoint;

		if (0 < movingTimeY)
		{
			++nowPoint.y;
			MoveNextPoint(nowPoint, targetPoint, nowTime + 1, targetTime, movedPoint);
		}
		else if (0 > movingTimeY)
		{
			--nowPoint.y;
			MoveNextPoint(nowPoint, targetPoint, nowTime + 1, targetTime, movedPoint);
		}
		nowPoint = tempPoint;

		//// 목표지�까지 시간� 여유가 있�때 ////
		if (abs(movingTimeX) + abs(movingTimeY) < targetTime - nowTime)
		{
			const int ADD_POINT_X[5] = {0, +1, -1, 0, 0};
			const int ADD_POINT_Y[5] = {0, 0, 0, +1, -1};
			for (register int i = 0; i < 5; ++i)
			{
				nowPoint.x += ADD_POINT_X[i];
				nowPoint.y += ADD_POINT_Y[i];
				MoveNextPoint(nowPoint, targetPoint, nowTime + 1, targetTime, movedPoint);
				nowPoint = tempPoint;
			}
		}
		movedPoint.pop_back();
	}
}

void KillSameThing()
{
	for (register int i = 0; i < (int)g_maxPoints.size(); ++i)
	{
		for (register int j = i + 1; j < (int)g_maxPoints.size(); ++j)
		{
			bool isSame = TRUE;
			for (register int k = 0; k < (int)g_maxPoints[i].size(); ++k)
			{
				if (g_maxPoints[i][k].x != g_maxPoints[j][k].x || g_maxPoints[i][k].y != g_maxPoints[j][k].y)
				{
					isSame = FALSE;
					break;
				}
			}
			if (isSame)
			{
				g_maxPoints.erase(g_maxPoints.begin() + j);
				--i;
				break;
			}
		}
	}
}

void main()
{
	for (int testCaseNumber = 1; ; ++testCaseNumber)
	{
		int cityWidth, cityHeight, keepTime;
		scanf("%d %d %d", &cityWidth, &cityHeight, &keepTime);

		if (0 == cityWidth && 0 == cityHeight && 0 == keepTime)
			break;

		InitCityMap(cityWidth, cityHeight, keepTime);

		int numberOfMessage;
		scanf("%d", &numberOfMessage);

		int receiveTime, left, top, right, bottom;
		for (register int i = 0; i < numberOfMessage; ++i)
		{
			scanf("%d %d %d %d %d", &receiveTime, &left, &top, &right, &bottom);
			SetMessagePoints(receiveTime, left, top, right, bottom);
			if (g_saveMessageTime.end() == find(g_saveMessageTime.begin(), g_saveMessageTime.end(), receiveTime - 1))
				g_saveMessageTime.push_back(receiveTime - 1);
		}
		SetCanMovePoints();
		bool isEscaped = FALSE;
		for (register int i = 0; i < keepTime; ++i)
		{
			if (0 == g_canMovePoints[i].size())
			{
				isEscaped = TRUE;
			}
		}
		for (register int i = 0; i < (int)g_canMovePoints[0].size(); ++i)
		{
			vector<POINT> movedPoint;
			MoveNextPoint(g_canMovePoints[0][i], g_canMovePoints[0][i], 0, 0, movedPoint);
		}
		KillSameThing();
		cout << "Robbery #" << testCaseNumber << ":" << endl;
		if (0 == g_maxPoints.size() && 0 != g_saveMessageTime.size())
		{
			cout << "The robber has escaped." << endl;
		}
		else if (1 == g_maxPoints.size() && keepTime == g_maxPoints[0].size() + 1)
		{
			for (register int i = 0; i < (int)g_maxPoints[0].size(); ++i)
			{
				cout << "Time step " << i + 1 << ": The robber has been at " << g_maxPoints[0][i].x + 1 << "," << g_maxPoints[0][i].y + 1 << "." << endl;
			}
		}
		else
		{
			cout << "Nothing known." << endl;
		}
		cout << endl;
	}
}
----
Robbery
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:27:55
Processing time 0.1179 sec