https://www.acmicpc.net/problem/13567
로봇은 명령어를 읽어 들여 정사각형 영역 S를 x축 또는 y축과 평행한 방향으로 움직인다. S의 왼쪽 아래 꼭짓점은 (0, 0)이고, 오른쪽 위의 꼭짓점은 (M, M)이다. 처음에 로봇은 (0, 0)에 위치해 있고, 동쪽 방향을 향하고 있다.
명령어는 로봇이 현재 위치에서 행할 동작과 그 동작과 관련된 값으로 주어진다. 동작은 두 가지가 있는데, TURN과 MOVE이다.
- TURN 0: 현재 위치에서 왼쪽으로 90도 회전
- TURN 1: 현재 위치에서 오른쪽으로 90도 회전
- MOVE d: 로봇이 향하고 있는 방향으로 d만큼 움직이기
명령 수행 후 로봇이 S의 범위를 벗어난다면 이 명령어는 유효하지 않다. 일련의 명령어 열을 이루는 각 명령어가 모두 유효하다면, 이 명령어 열을 유효하다고 한다.
한 변의 길이가 M인 정사각형과 n개의 명령어, 그리고 로봇이 (0, 0) 위치에서 시작해 동쪽을 바라보고 있을 때, n개의 명령어를 따라 움직였을 때의 최종 위치를 출력하는 문제다.
문제 탐색하기
- 문제에서 구해야 하는 최종 정답은 무엇인지 탐색한 과정
- 그 정답을 구하기 위해 어떻게 코드를 구현해야 할지 고민한 과정
- 문제에 들어오는 범위를 파악하며 어떤 알고리즘을 쓸 수 있을지 고민해 가는 과정
ex. 가능한 시간 복잡도, 알고리즘 선택
입출력 제한
- 1 ≤ M ≤ 1,000
- 1 ≤ n ≤ 1,000
- dir = 0 or 1
- 1 ≤ d ≤ 1,000
N개의 명령어를 입력받으면서 앞에 TURN이 오면 뒤에 오는 숫자에 따라 회전하고, MOVE가 오면 뒤에 오는 숫자만큼 이동하면 된다. 이때 이동이 끝났는데 로봇의 좌표가 정사각형 영역을 벗어났다면 -1을 출력하고 프로그램을 종료하면 된다.
우하단으로 진행되는 일반적인 2차원 배열과는 다르게 정사각형 영역이 좌상단으로 진행되기 때문에 회전할 때 주의해야 하고 마지막에 좌표를 출력할 때 x와 y 값을 바꿔서 출력해야 한다.
코드 설계하기
위의 [문제 탐색하기]에서 고민한 과정을 토대로 문제 풀이에 대한 실마리를 잡고, 문제 풀이를 본격적으로 하기 전 이 문제를 풀기 위한 로드맵을 그리는 과정!
- 어떤 순서로 코드를 작성해야 할지
- 어떤 함수들을 작성해야 할지
- M, N 입력받기
- N개의 명령어와 정수를 입력받으면서 MOVE와 TURN에 따라 정수만큼 이동하거나 회전하기
- 한 번 이동한 후 로봇의 좌표가 정사각형 영역을 벗어난다면(명령어 열이 유효하지 않다면) -1을 출력하고 프로그램 종료하기
- 로봇의 마지막 좌표 출력하기
시도 회차 수정 사항 (Optional)
- '틀렸습니다'를 받았다면 왜 틀렸는지 고민해 보고, 어떻게 수정할 수 있는지 고민하는 과정을 작성
- 내가 세울 설계에서 어떤 부분이 틀렸는지도 함께 점검
- 한 번에 맞히면 pass해도 됨!
1회차
- 왼쪽 아래가 (0, 0)이고 오른쪽 위가 (M, M)이기 때문에 명령어를 입력받고 마지막 좌표를 출력할 때 x와 y를 바꿔서 출력해야 함
정답 코드
#include <iostream>
using namespace std;
int m,n,a,d,x,y,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
string str;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> m >> n;
while (n--) {
cin >> str >> a;
if (str.compare("MOVE")==0) {
for (int i=0; i<a; i++) {
x+=dx[d];
y+=dy[d];
}
if (x<0 || y<0 || x>=m || y>=m) {
cout << -1;
return 0;
}
}
else {
if (a==0) d=(d+1)%4;
else d=(d+3)%4;
}
}
cout << y << ' ' << x;
}