[백준 C++] 20493 세상은 하나의 손수건

이성훈·2022년 3월 3일
0

문제

오래된 운동화를 신고, 시원한 공기와 투명한 하늘 아래 따뜻한 햇빛을 받으며 새로 마주하는 이 거리와 손잡고 걷는다. 복잡한 생각 없이 설레는 마음으로 걷다 보면 뛰고 싶고, 같이 달리다 보면 숨이 차다. 헐떡거리며 주저앉는 순간에도, 세상은 한 장의 손수건 같다.

준원이는 천하제일코딩대회가 진행 중인 지금 구름같이 행복한 하루를 보내고 있지만, 애석하게도 여러분은 문제를 풀어야 한다. 준원이가 오늘 에버랜드 대신 x축과 y축이 있는 좌표평면의 원점에서 걷고 있다고 생각해보자. 준원이의 초기 위치는 (0, 0)이고, x축 방향으로 초당 1의 속도로 움직이고 있다. 즉, 매초 준원이의 x좌표가 1만큼 증가하고 있다. 그렇지만 준원이는 가끔씩 방향을 바꾼다. 방향을 바꿀 때에는 왼쪽으로 90도만큼 돌거나 오른쪽으로 90도만큼 돈다.

준원이가 방향을 바꾼 기록이 입력으로 주어졌을 때, 준원이가 T초간 걸어간 이후 도착했을 좌표를 구하는 프로그램을 작성하시오.

입력

첫째 줄에는 준원이가 방향을 바꾼 횟수 N과, 준원이가 걸어간 시간 T가 공백을 사이에 두고 주어진다.

이후 N개의 줄에, 준원이가 i번째로 방향을 바꾼 시간 Ti과, 준원이가 왼쪽으로 돌았는지 또는 오른쪽으로 돌았는지 나타내는 문자열 Si가 공백을 사이에 두고 주어진다. Si는 준원이가 왼쪽으로 돌았으면 left이고, 오른쪽으로 돌았으면 right이다.

출력

준원이가 T초간 걸어간 이후 도착한 좌표가 (x, y)라면, x와 y를 차례로 공백을 사이에 두고 출력한다.

제한

0 ≤ N ≤ 100,000
1 ≤ T ≤ 1,000,000,000
0 ≤ Ti ≤ T
T1, ..., TN은 모두 서로 다르고, 증가 수열이다. 즉, 한 시점에 방향을 여러 번 바꾸지 않으며, 시간 순서대로 입력이 주어진다.
Si = left 또는 right

풀이

제한조건을 보니, 입력값들모두 int선에서 가능하고 1초시간내에 풀수있으므로 특별한 제한이없다.

이문제도 방향을 나타내는 변수 flag를 잘써먹고, 여러줄로 입력받은 시간과 방향정보를
vector에 담아서 처리하면 된다.
=> 사실 2차원 배열을 이용해도된다.

먼저 입력값들을 받는다.


여기서 첫번째 scanf로 정수와 줄바꿈문자이전까지의 문자열을 입력받고,
두번째 scanf로 줄바꿈문자를 지운다.
여기서 읽어들인 시간과 문자열이 right인지 left인지 판독하여 정수 0, 1 로 변환하여 vector에 담았다.

이제 준원이가 움직이는 부분이다.


방향을 기록하는 flag 변수를 이용하여 좌표계에서 방향마다 이동하는 위치를 코딩해주면된다.
이동후에는 바라보는 방향과 이전시간을 갱신해준다.

여기서 빼먹으면안되는것이 n개의 줄로 시간과 방향을 입력받아서 전부 수행후 전체시간 t를 못채웠을경우 현재 방향대로 전진하도록 코드를 추가한다.

#define _CRT_SECURE_NO_WARNINGS 
#include <bits/stdc++.h>

int main(void) {
	int n, t;
	//준원이초기위치 locX, locY, 이전 시간 preTime
	int locX = 0, locY = 0, preTime = 0; 
	scanf("%d %d\n", &n, &t);
	//n개의 방향을 바꾼 기록을 저장
	//2번째 요소는 0:left 1:right
	std::vector<std::pair<int, int>> list; 

	//입력값을 모두 저장
	for (int i = 0; i < n; i++) {
		int time;
		int dir;
		char flag[7];
		scanf("%d %[^\n]s", &time, &flag); //시간과 방향을 읽음
		scanf("%c", &flag[6]); //줄바꿈문자를 지움
		if (flag[0] == 'r') {
			dir = 0;
		}
		else {
			dir = 1;
		}
		list.push_back({ time, dir });
	}

	//0 : →
	//1 : ↓
	//2 : ←
	//3 : ↑
	int flag = 0; //처음엔 오른쪽으로 전진
	//이전과 다음 입력값을 기준으로 준원이의 위치를 기록
	for (int i = 0; i < list.size(); i++) {
		int time = list[i].first;
		int f = list[i].second;

		int moveGap = time - preTime; //이동할 시간차(=거리)
		

		//현재 바라보는 방향으로 시간차 만큼 이동.
		if (flag == 0) {
			locX += moveGap; 
		}
		else if (flag == 1) {
			locY -= moveGap;
		}
		else if (flag == 2) {
			locX -= moveGap;
		}
		else if (flag == 3) {
			locY += moveGap;
		}

		//다음에 이동할 방향 지정
		if (f == 0) {
			flag++;
		}
		else if (f == 1) {
			flag--;
		}

		//한바퀴를 돈경우
		if (flag == 4) {
			flag = 0;
		}
		else if (flag == -1) {
			flag = 3;
		}

		preTime = time; //이전시간 갱신
	}

	//아직 시간이 남은경우
	if (preTime != t) { 
		//마지막으로 바라보던 방향으로 남은 시간만큼 이동.
		if (flag == 0) {
			locX += t - preTime;
		}
		else if (flag == 1) {
			locY -= t - preTime;
		}
		else if (flag == 2) {
			locX -= t - preTime;
		}
		else if (flag == 3) {
			locY += t - preTime;
		}
	}

	printf("%d %d", locX, locY);

	return 0;
}
profile
I will be a socially developer

0개의 댓글