프로그래머스 LV 2 당구 연습
문제 : https://school.programmers.co.kr/learn/courses/30/lessons/169198
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
1. 문제 풀이 : 굉장히 어려웠다..ㅠㅠ
당구 쿠션을 칠 때 계산하는 거였는데 처음에는 직접 피타고라스의 정리로 계산해서 풀려 했다.
주어진 1,2,3번 case를 모두 손수 계산해봤고 그 결과 balls[i][0] , balls[i][1] 을 endX, endY로 맞춰서 startX, startY와 거리 계산을 해야함을 깨달았다. 그러나 직접 대각선을 일일이 계산하기엔 번거로웠고 직선형태로 만들어줘야 편함을 느꼈는데 어떻게 해야할 지 감이 안왔는데 이 부분은 검색 결과 입사각과 반사각을 통해 "대칭"을 만들어서 직선거리로 만들어주는 스킬을 배웠다.
2. FeedBack
경우의 수를 나누었고 상 , 하 , 좌 , 우 벽을 나누어서 계산했다. 각각의 벽에 쿠션을 줬을 때 입사각과 반사각이 동일하다는 조건이 있으므로 대칭 관계를 이룰 수 있었고 각각의 벽을 하나의 축으로 하여서 A가 내가 칠 공, B를 목표로 하는 공이라 치면 B의 대칭 좌표를 C라 칭한 뒤 A와 C의 직선거리를 구했다.
정리하자면
* x1 : startX , x2 : endX , y1: startY , y2 : endY
1) 상 : C의 좌표는 x 좌표는 B와 동일하다. y 좌표는 n - y2를 만큼 더 올라가기 때문에 이를 계산해줬고 즉 2 * n - y2가 나왔다 그래서 이를 통해 두 점사이의 거리를 이용해서 거리의 제곱을 구해줬다.
2) 하 : C의 좌표도 마찬가지로 x좌표는 B와 동일하며 y좌표는 m 즉, x축에 대칭을 해주기 때문에 -y2가 된다.
마찬가지로 두 점사이의 거리 공식을 사용해서 거리의 제곱을 구해준다.
3) 좌 : C의 좌표는 n, y축 대칭이기 때문에 -x2가 된다. y좌표는 그대로다. 그래서 이를 위 사례들과 같이 거리의 제곱을 구해줬다.
4) 우 : C의 좌표는 상의 좌표와 같은 케이스로 계산하면 편하다. 이번엔 이를 x좌표에 적용시키면 되고 x좌표니깐 n대신 m을 사용해서 2 * m - x2가 된다.
3. 예외처리
: 물론 문제에 나와 있는대로 예외 처리를 해줘야 한다. 예시를 들자면
1) 상 => A와 B가 x값이 일정해서 수직으로 일치하고 y좌표만 B가 더 클 때, 이 경우에는 벽에 부딪히기 전에 공끼리 부딪히기 때문에 예외 처리 해주어야 한다.
2) 하 => 상과 동일하지만 y좌표가 A가 더 클 때를 입력해준다.
3) 좌 => 두 공이 수평으로 일치하고 (A,B의 x좌표 같음) , 왼쪽 벽을 맞춰야 하니 A가 B보다 x좌표가 더 클 때를 생각해서 예외 처리해준다.
4) 우 => 좌 경우에서 반대의 케이스를 계산해준다.
4. 정답 코드
5. 시간복잡도 및 배운 점
: 경우의 수를 나누는 경우와 예외 처리를 하는 유형이 거의 모든 유형인데도 아직 익숙치가 않다.. 파이썬 abs 절댓값도 뒤늦게 깨달은 점을 보면 ts 뿐 아니라 파이썬도 열심히 해야겠단 생각이 들었다.
: 시간 복잡도는 balls의 길이만큼 반복문을 진행하므로 O(N)이라고 생각했다.