어제 프로그래머스에서 자바스크립트로 문제를 풀고 있었는데 푼 사람이 0인, 새로운 문제가 올라왔다.
난이도도 1이길래 빠르게 풀고 넘어가려고 했는데, 은근 생각할 게 있어서 시간이 걸렸다. 그리고 무엇보다 재밌었다.
난이도가 1인 이유는 수학 공식만 알면 쉽게 풀 수 있기 때문이라고 추측한다.. 공식을 모르면 굉장히 어렵고, 나도 오랜만에 구글링으로 수학 공식을 검색해서 풀었다.
문제에 필요한 개념을 알기 위해 문제 내용 중 다음 조건에 주목해야 한다.
단, 머쓱이가 친 공이 벽에 부딪힐 때 진행 방향은 항상 입사각과 반사각이 동일하며, 만약 꼭짓점에 부딪힐 경우 진입 방향의 반대방향으로 공이 진행됩니다.
처음엔 별 거 아닌 조건이라고 생각하고 직각 삼각형의 빗변 구하는 공식으로 풀려고 했으나, 그렇게 되면 너무 복잡해서 더 이상 난이도 1의 문제가 아닌 것 같았다.
그래서 입사각과 반사각 키워드로 검색을 한 결과 한 블로그 내용이 눈에 들어왔다.
이 예시는 중학생들의 수학적 사고력을 기르기 위한 것인데 딱 이 문제에 필요한 개념이었다.
특히, 이를 이용한 당구 예시도 있었다.
위 사진을 보게 되면 이제 접근법을 알 것이다. 시작점의 좌표를 반전시키고 두 공 사이의 거리를 구하면 된다.
단, 반드시 원쿠션을 해야 하므로 벽에 부딪치지 않는 경우는 제외해야 한다.
제가 푼 코드는 다음과 같습니다.
function solution(m, n, startX, startY, balls)
{
const answer = [];
const d = [[startX, 2*n-startY], [startX, -startY], [-startX, startY], [2*m-startX, startY]];
for(let i=0; i<balls.length; i++)
{
let maxValue = Number.MAX_VALUE;
for(let j=0; j<4; j++)
{
const [newX, newY] = d[j];
if(newX === balls[i][0])
{
const maxY = Math.max(startY, newY);
const minY = Math.min(startY, newY);
if(minY < balls[i][1] && balls[i][1] < maxY)
continue;
}
if(newY === balls[i][1])
{
const maxX = Math.max(startX, newX);
const minX = Math.min(startX, newX);
if(minX < balls[i][0] && balls[i][0] < maxX)
continue;
}
const tmp = (newX - balls[i][0]) **2 + (newY - balls[i][1]) **2;
maxValue = Math.min(maxValue, tmp);
}
answer.push(maxValue);
}
return answer;
}
참고한 블로그 출처를 남깁니다.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=yh6613&logNo=220147018035
'알고리즘' 카테고리의 다른 글
자바스크립트로 알고리즘 풀기 (0) | 2023.03.15 |
---|---|
동적 계획법(Dynamic Programming) (1) | 2023.02.06 |