배열로 works가 존재하는데 n만큼 배열에 숫자를 감소시켜 각각의 값들의 제곱의 합이 최소가 되게 만들기 => (나의정리) 감소를 전부 시켰을때 모든 숫자들의 각각의 차이가 심하지않고 고르게 분포시키기
works | n | result |
---|---|---|
[4, 3, 3] | 4 | 12 |
[2, 1, 2] | 1 | 6 |
[1,1] | 3 | 0 |
마치 테트리스를 가장 낮은 높이로 만드는 것과 비슷하다고 생각
배열을 내림차순으로 정렬하고 일단 초반값은 높으므로 감소를 시키면서 만약
처음값과 그다음값이 같다면 그다음 값도 감소를 시켜준다. 그 다음값도 같다면 감소를 시켜주고
첫번째값 + 1 !== 두번째값
(같은값이 아니라면) 혹은 n===0
(감소할 n이 없다면) 이라면 for문을 나온다.=>같은 값이 아니라면은 즉, i의 이전높이와 i+1의 높이가 다르다는건 i의 높이가 워낙 높아 i의 높이가 i+1와 같아지기 전까지는 for문 반복을 진행하지않고 break문을 진행한다는 의미와 같다.
3 3 2 면 3이 영향받아 1줄고 2+1 = 3인지 확인해서 맞으니 그옆의 3도 감소시키는 것이 가능하지만
5 3 2 면 5가 영향받고 1줄고 4+1 = 3이 아니므로 그옆의 3을 감소시키는 것이 아닌 아직 큰 값인 4를 감소시키기 위해 for문을 break로 나온다.
function solution(n, works) {
works.sort((a,b)=>(b-a)) //(2)
if(works.reduce((acc,val)=>acc+val ,0) < n ) //(1)
return 0;
while(n>0) //(3)
{
for(let i=0;;i++)
{
works[i]--; //(4)
n--;
if(works[i]+1 !== works[i+1] || n===0)
break;
}
}
return works.reduce((acc,val)=>acc+val*val ,0); //(5)
}
방법만 제대로 고민할 수 있다면 어려운 문제는 아니다.
코드 짜는 시간 이상으로 코드를 어떻게 제대로 짜야할지 고민하는 시간이 중요하다.