본문 바로가기
백준/그래프

백준 14503 c++ "로봇 청소기" -[PlusUltraCode]

by PlusUltraCode 2024. 4. 25.

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

 

14503번: 로봇 청소기

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽

www.acmicpc.net

 

[필자 사고]

단순 구현 문제이다. 먼저 문제에서 주어진 조건들을 잘 따라오면서 코드를 작성하면 쉽게 풀릴 수 있다.

 

필자는 로봇이라는 객체를 하나 구현해서 문제를 풀어 나갔다.

 

 

[소스 코드]

#include<iostream>
#include <vector>
using namespace std;

class Robot {
public:
	int sero;
	int garo;
	int see; //0 1 2 3 
	int cleanCount;

public:
	Robot() {
		sero = 0;
		garo = 0;
		see = 0;
		cleanCount = 0;
	}

	void InitRobot(int sero,int garo, int see) {
		this->sero = sero;
		this->garo = garo;
		this->see = see;

	}

	void Rotate() {
		if (see == 0) {
			see = 3;
			return;
		} 

		see -= 1;
	}

	void MoveToFront() {
		if (see == 0) {
			sero--;
		}
		if (see == 1) {
			garo++;
		}
		if (see == 2) {
			sero++;
		}
		if (see == 3) {
			garo--;
		}
	}

	void MoveToBack() {
		if (see == 0) {
			sero++;
		}
		if (see == 1) {
			garo--;
		}
		if (see == 2) {
			sero--;
		}
		if (see == 3) {
			garo++;
		}
	}

	void NowAreaClean();
	
};

int dy[4] = { 0,1,0,-1 };
int dx[4] = { 1,0,-1,0 };

typedef pair<int, int> node;
vector<vector<int>> arr;
vector<vector<bool>> cleanArea;
Robot robot;
int N, M;

void Robot::NowAreaClean() {
	if (cleanArea[sero][garo] == false) {
		cleanArea[sero][garo] = true;
		cleanCount++;
	}
}

void Input() {

	cin >> N >> M;
	int sero, garo, see;
	cin >> sero >> garo >> see;
	robot.InitRobot(sero, garo, see);
	arr.resize(N);
	cleanArea.resize(N);

	for (int i = 0; i < N; i++) {
		arr[i].resize(M);
		cleanArea[i].resize(M, false);
	}

	for (int i = 0; i < N; i++) {
		for (int k = 0; k < M; k++) {
			int num;
			cin >> num;
			if (num == 1) {
				arr[i][k] = 1;
				cleanArea[i][k] = true;
			}
			else {
				arr[i][k] = 0;
			}
		}
	}

}

bool Inside(int sero, int garo) {
	if (sero >= 0 && sero < N && garo >= 0 && garo < M) {
		return true;
	}
	return false;
}

bool RoundClean() {

	int sero = robot.sero;
	int garo = robot.garo;

	for (int i = 0; i < 4; i++) {
		int nextSero = sero + dy[i];
		int nextGaro = garo + dx[i];

		if (Inside(nextSero, nextGaro) == false)continue;
		if (arr[nextSero][nextGaro] == 1)continue;
		if (cleanArea[nextSero][nextGaro] == false) {
			return false;

		}

	}
	
	return true;
}

node WhatIsFront() {
	int nowSero = robot.sero;
	int nowGaro = robot.garo;
	int see = robot.see;
	if (see == 0) {
		nowSero--;

	}
	if (see == 1) {
		nowGaro++;
	}
	if (see == 2) {
		nowSero++;
	}
	if (see == 3) {
		nowGaro--;
	}
	return { nowSero,nowGaro };
}

node WhatIsBack() {
	int nowSero = robot.sero;
	int nowGaro = robot.garo;
	int see = robot.see;
	if (see == 0) {
		nowSero++;

	}
	if (see == 1) {
		nowGaro--;
	}
	if (see == 2) {
		nowSero--;
	}
	if (see == 3) {
		nowGaro++;
	}

	return { nowSero,nowGaro };
}

void GameStart() {
	int nowSero = robot.sero;
	int nowGaro = robot.garo;
	
	while (1) {
		robot.NowAreaClean();
		if (RoundClean()==true) {
			node nowNode = WhatIsBack();
			int nextSero = nowNode.first;
			int nextGaro = nowNode.second;

			if (Inside(nextSero, nextGaro) == false||
				arr[nextSero][nextGaro]==1) return;
			
			robot.MoveToBack();
			continue;
		}

		for (int i = 0; i < 4; i++) {
			robot.Rotate();
			node nowNode = WhatIsFront();
			int nextSero = nowNode.first;
			int nextGaro = nowNode.second;

			if (Inside(nextSero, nextGaro) == false)continue;
			if (arr[nextSero][nextGaro] == 1)continue;
			if (cleanArea[nextSero][nextGaro] == false) {
				robot.MoveToFront();
				break;
			}
		}

		
	}
}

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	Input();
	GameStart();
	cout << robot.cleanCount;
}