당구대의 가로 길이 m, 세로 길이 n과 머쓱이가 쳐야 하는 공이 놓인 위치 좌표를 나타내는 두 정수 startX, startY, 그리고 매 회마다 목표로 해야하는 공들의 위치 좌표를 나타내는 정수 쌍들이 들어있는 2차원 정수배열 balls가 주어집니다. "원쿠션" 연습을 위해 머쓱이가 공을 적어도 벽에 한 번은 맞춘 후 목표 공에 맞힌다고 할 때, 각 회마다 머쓱이가 친 공이 굴러간 거리의 최솟값의 제곱을 배열에 담아 return 하도록 solution 함수를 완성해 주세요.
제한사항
3 ≤ m, n ≤ 1,000
0 < startX < m
0 < startY < n
2 ≤ balls의 길이 ≤ 1,000
balls의 원소는 [a, b] 형태입니다.
a, b는 머쓱이가 맞춰야 할 공이 놓인 좌표를 의미합니다.
0 < a < m, 0 < b < n
(a, b) = ( startX, startY )인 입력은 들어오지 않습니다.
쿠션이 되는 조건과 쿠션이 된다면 그 길이는? 수학적 계산이다.
쿠션이 되지 못하는 조건
1. sx == tx이고 sy > ty이면, 아래로 원쿠션 불가능
2. sx == tx이고 sy < ty이면, 위로 원쿠션 불가능
3. sy == ty이고 sx > ty이면, 왼쪽으로 원쿠션 불가능
4. sy == ty이고 sx < ty이면, 오른쪽으로 원쿠션 불가능
이유는 공에 먼저 맞기 때문에.
double형의 경우 실수부 계산오차로 인해서 문제가 생기므로 int 형으로 풀어야한다.
코드
import java.util.*;
class Solution {
public int[] solution(int m, int n, int startX, int startY, int[][] balls) {
int[] answer = new int[balls.length];
for (int i = 0; i < balls.length; i++) {
int targetX = balls[i][0];
int targetY = balls[i][1];
ArrayList<ArrayList<Integer>> tlist =new ArrayList<>();
int curlen, len = Integer.MAX_VALUE;
// 좌
if (!(startY == targetY && startX > targetX)) {
ArrayList<Integer> list = new ArrayList<>();
list.add(targetX*-1);
list.add(targetY);
tlist.add(list);
}
// 우
if (!(startY == targetY && startX < targetX)) {
ArrayList<Integer> list =new ArrayList<>();
list.add(m+m-targetX);
list.add(targetY);
tlist.add(list);
}
// 상
if (!(startX == targetX && startY < targetY)) {
ArrayList<Integer> list = new ArrayList<>();
list.add(targetX);
list.add(n+n-targetY);
tlist.add(list);
}
// 하
if (!(startX == targetX && startY > targetY)) {
ArrayList<Integer> list = new ArrayList<>();
list.add(targetX);
list.add(targetY*-1);
tlist.add(list);
}
for(ArrayList<Integer> k : tlist){
int tmp = cal(k,startX,startY);
len= Math.min(tmp,len);
}
answer[i] = len;
}
return answer;
}
int cal(ArrayList<Integer> k,int startX, int startY){
int bigX = Math.max(startX, k.get(0));
int smallX = Math.min(startX, k.get(0));
int bigY = Math.max(startY, k.get(1));
int smallY = Math.min(startY, k.get(1));
return (int)Math.pow(bigX - smallX, 2) + (int)Math.pow(bigY - smallY, 2);
}
}