728x90

문제

로고는 주로 교육용에 쓰이는 프로그래밍 언어이다. 로고의 가장 큰 특징은 거북이 로봇인데, 사용자는 이 거북이 로봇을 움직이는 명령을 입력해 화면에 도형을 그릴 수 있다.

거북이는 위치와 각도로 표현할 수 있다. 거북이는 입에 연필을 물고 있는데, 연필을 내리면 움직일 때 화면에 선을 그리고, 올리면 선을 그리지 않고 그냥 지나가기만 한다.

제일 처음에 거북이는 (0,0)에 있고, 거북이가 보고 있는 방향은 y축이 증가하는 방향이다. 또한 연필은 내리고 있다.

사용자는 다음과 같은 다섯가지 명령으로 거북이를 조정할 수 있다.

  1. FD x: 거북이를 x만큼 앞으로 전진
  2. LT a: 거북이를 반시계 방향으로 a도 만큼 회전
  3. RT a: 거북이를 시계 방향으로 a도 만큼 회전
  4. PU: 연필을 올린다
  5. PD: 연필을 내린다.

축에 평행한 직사각형 N개가 주어졌을 때, 이 직사각형을 그리는데 필요한 PU 명령의 최솟값을 구하는 프로그램을 작성하시오.

거북이는 같은 선을 여러 번 그릴 수 있지만, 문제에 주어진 직사각형 N개를 제외한 직사각형을 그릴 수 없다. 거북이의 크기는 아주 작아서 좌표 평면의 한 점이라고 생각하면 된다. 직사각형의 변은 축에 평행하다.

입력

첫째 줄에 직사각형의 개수 N이 주어진다. (1 ≤ N ≤ 1000)

다음 N개의 줄에는 직사각형의 좌표 x1, y1, x2, y2가 주어진다. (−500 ≤ x1 < x2 ≤ 500), (−500 ≤ y1 < y2 ≤ 500) (x1, y1)는 직사각형의 한 꼭짓점 좌표이고, (x2, y2)는 그 점의 대각선 방향의 반대 꼭짓점의 좌표이다.

출력

N개의 직사각형을 그리는 필요한 PU명령의 최솟값을 출력한다.


까다로운 한 붓 그리기 문제이다. 

좌표의 범위가 음수도 포함하므로 배열로 방문 여부를 표시할 수가 없다.

이를 위해 500을 더하는 방식으로 할 수도 있지만, 500만 더하면 겹치지 않는 직사각형을 방문할 여부가 있으므로 

500을 더하고 2를 곱해준다.

그 후로 직사각형의 각 점을 하나씩 방문하며 방문했다는 값으로 변경해준다. 

주의할 점은 문제에서 맨 처음 시작할 때 0,0에서 펜을 내린 상태이므로 1000, 1000에 방문을 했다면 1을 빼주자.

 

 

코드 원본 : https://github.com/chosh95/STUDY/blob/master/BaekJoon/2020/%EB%A1%9C%EA%B3%A0%20(3108%EB%B2%88).cpp

 

chosh95/STUDY

프로그래밍 문제 및 알고리즘 정리. Contribute to chosh95/STUDY development by creating an account on GitHub.

github.com

C++ 코드

#include <iostream>
using namespace std;
int N, res;
int p[2002][2002];
int dx[4] = { -1,0,0,1 };
int dy[4] = { 0,-1,1,0 };

void dfs(int x, int y) {
	p[x][y] = 2;

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx < 0 || ny < 0 || nx>2000 || ny>2000) continue;
		if (p[nx][ny] == 0 || p[nx][ny] == 2) continue;
		dfs(nx, ny);
	}
}
int main()
{
	cin >> N;
	int x1, y1, x2, y2;
	for (int i = 0; i < N; i++) {
		cin >> x1 >> y1 >> x2 >> y2;
		x1 = (x1 + 500) * 2;
		y1 = (y1 + 500) * 2;
		x2 = (x2 + 500) * 2;
		y2 = (y2 + 500) * 2;
		for (int j = y1; j <= y2; j++) 
			p[x1][j] = p[x2][j] = 1;
		for (int j = x1; j <= x2; j++)
			p[j][y1] = p[j][y2] = 1;
	}

	for (int i = 0; i <= 2000; i++) {
		for (int j = 0; j <= 2000; j++) {
			if (p[i][j] == 1) {
				res++;
				dfs(i, j);
			}
		}
	}

	if (p[1000][1000] == 2) res--; //(0,0)에서 붓을 내린채로 시작하므로
	cout << res;
}

 

728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 암호 만들기 (1759번)  (0) 2020.03.05
[백준] 알파벳 (1987번)  (0) 2020.03.05
[백준] 문자판 (2186번)  (0) 2020.03.04
[백준] 보물섬 (2589번)  (0) 2020.03.04
[백준] DSLR (9019번)  (0) 2020.03.03

+ Recent posts