https://www.acmicpc.net/problem/1876
1876번: 튕기는 볼링공
첫째 줄에 테스트 케이스의 개수 N이 주어진다. 다음 N개 줄에는 볼링공과 핀 사이의 거리 T (16.0 ≤ T ≤ 18.0)와 공을 던진 각도 X (중심을 기준으로 계산, 10 ≤ X ≤ 80)가 주어진다.
www.acmicpc.net
여러 가지 실수를 했기 때문에 조금 아쉬웠다.
문제 자체는 쉬운 편이었으나 삼각함수를 활용하다가 실수를 해서 자꾸 틀렸다.
접근
볼링공을 굴렸을 때 범퍼에 부딪치면 입사각과 같은 각도로 튕겨진다. 범퍼가 아래에만 있는게 아니라 위에도 있으므로 양 옆 범퍼를 모두 부딪치면서 전진하게 된다.
문제를 푸는 방법은 볼링공을 움직이면서 볼링공과 핀의 거리를 구했을 때 둘의 반지름을 합한 값보다 작은 상황이 있는지 검사하면 된다.
그런데 양 범퍼를 부딪치며 전진하는 볼링공과 핀의 거리를 구하기 매우 어려우므로 단순하게 볼링공이 레인의 중앙에 있을 때만 확인하기로 했다.
볼링공이 이동할 때 핀과 접하게 된다면 볼링공이 레인의 중앙에 있을 때 볼링공과 핀의 거리는 //[a+b]//이다.
만약 볼링공이 이동할 때 핀과 부딪친다면 볼링공과 핀의 거리는 //[a+b]//보다 더 짧을 것이다. 그렇지 않다면 부딪치지 않을 것이다.
입사각이 주어졌고, 볼링공과 핀의 반지름도 주어졌으므로
$$ a+b = {6\over{cos{({\pi\over 2}-\theta)}}} + {10\over{cos{({\pi\over 2}-\theta)}}} = {6\over{sin\theta}} + {10\over{sin\theta}} \\ = {16\over{sin\theta}}$$
사진에서 알 수 있듯이 볼링공이 접하는 경우는 두 가지가 있으므로 볼링공이 //[ (T-a-b, T+a+b) ]//범위 내에 있다면 충돌임을 알 수 있다.
이제 볼링공을 움직여 보면서 거리가 가까운 상황이 있는지 검사하자.
볼링공이 범퍼와 부딪치고 다시 레인의 중앙으로 왔을 때 얼마나 이동했는지 알기 위해 다음 사진을 참고하자.
레인의 절반은 //[105/2=52.5]//다. 볼링공이 범퍼를 쳤을 때 볼링공의 반지름을 고려해야 하므로 세로는 //[52.5-10 = 42.5]//다.
따라서 //[x = {42.5\over{tan\theta}}]//인데, 부딪친 후 다시 중앙으로 향하므로 2를 곱해야한다.
한 번 부딪쳤을 때 이동거리 //[ = 2x = {85\over{tan\theta}} ]//
따라서 0부터 //[T * 100]//까지 이동거리를 누적시키면서 충돌 범위 내에 있었는지 검사하면 된다.
미흡했던 점
문제 분석은 30분만에 끝냈지만 코드를 짜는 과정에서 라디안과 각의 관계, 삼각함수 사용법 등 실수를 했다.
//[180\degree = \pi, 1rad = {\pi\over{180\degree}}]//이다. cmath의 삼각함수들은 전부 radian으로 값을 입력받아야 하는데 이걸 모르고 degree를 그대로 입력했다. 이런 관계는 암기가 되어 있어야 한다.
#include <cmath>
#include <iostream>
#define PI 3.14159265
int main() {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
double T, dist = 0;
int X;
scanf("%lf %d", &T, &X);
double left = T * 100 - (16.0 / sin(PI * X / 180.0)),
right = T * 100 + (16.0 / sin(PI * X / 180.0)),
step = 85.0 / tan(PI * X / 180.0);
while (dist < right) {
if (left < dist && dist < right) {
printf("yes\n");
break;
}
dist += step;
}
if (dist >= right) {
printf("no\n");
}
}
}
'프로그래밍 > 알고리즘' 카테고리의 다른 글
9465 스티커 (0) | 2022.09.10 |
---|---|
2502 떡 먹는 호랑이 (0) | 2022.09.07 |
4105 유클리드 (0) | 2022.09.05 |
2527 직사각형 (0) | 2022.09.03 |
18187 평면 분할 (0) | 2022.09.03 |
댓글