알고리즘/문제 풀이
백준 19953번: 영재의 산책
Themion
2022. 5. 4. 19:07
https://www.acmicpc.net/problem/19953
19953번: 영재의 산책
영재는 알고리즘 문제를 푸는 것을 좋아한다. 하지만 잘 풀지는 못하는 영재는 집중이 되지 않을 때 산책을 한다. 오늘도 집중이 되지 않아 영재는 동네를 산책한다. 영재의 동네는 2차원 좌표로
www.acmicpc.net
영재의 산책 속력을 각 초마다 나열해 보면 초기 속력을 제외한 속력의 주기는 4의 약수가 된다. 따라서 영재의 산책의 초기 속력을 제외하면 각 방향으로 이동하는 속력은 항상 같으므로, 이를 이용해서 영재의 최종 위치를 상수 시간 안에 계산할 수 있다.
#include <cstdio>
#define next_v (v * m) % 10
class coord {
public:
// 현재 좌표의 y, x값
int y, x;
// 생성자
coord() { this->y = this->x = 0; }
coord(int y, int x) { this->y = y; this->x = x; }
// 좌표의 덧셈 연산
coord operator+=(coord other) {
this->y += other.y;
this->x += other.x;
return *this;
}
// 좌표값을 num배한 좌표값
coord operator*(int num) {
return { this->y * num, this->x * num };
}
};
int main() {
// v: 영재의 속도, m: 속도 변위의 규칙, t: 총 산책 시간
int v, m, t, i = 0;
// ans: 영재의 최종 위치, add[i]: {북, 동, 남, 서}[i] 방향 변위값
coord ans, add[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
// 문제의 조건을 입력받은 뒤
scanf("%d %d %d", &v, &m, &t);
// 영재의 산책의 첫 k(<=4) 초 부분은 brute force로 계산한 뒤
while (!i || i % 4 != t % 4) {
ans += add[i++] * v;
v = next_v;
}
// 이후 각 방향으로의 산책 속도는 항상 일정하므로
// 해당 방향으로의 이동 거리를 변위 * 속도 * 시간을 통해 계산
for (int j = 0; j < 4; j++) {
ans += add[(i + j) % 4] * v * ((t - i) / 4);
v = next_v;
}
// 영재의 최종 위치를 형식에 맞게 출력
printf("%d %d\n", ans.x, ans.y);
return 0;
}