プログラマー-残業指数
13941 ワード
質問元:https://programmers.co.kr/learn/courses/30/lessons/12927
会社員のデミはたまに残業しますが、残業すると残業疲労度が溜まります.残業疲労度は、残業開始時の残量に1つの数値を乗じたものです.デミはN時間以内に残業疲労度を最小限に抑える.デミが1時間以内に1時間の仕事量を処理できると言った場合、退勤前の残りのN時間と各仕事の仕事量について、残業疲労度を最低値に下げる関数解を返してください.
せいげんじょうけん
worksは、長さが1より大きく、20000未満の配列です.
worksの要素は50000以下の自然数です.
nは1000000以下の自然数である.
入力例
works = [4, 3, 3] n = 4
works =[2, 1, 2] n = 1
works =[1,1] n = 3
サンプル出力
12
6
0
I/O例説明
I/O例#1
n=4の場合、残りの仕事量が[4,3]の場合、残業指数を最小化するために4時間働いた結果は[2,2,2]であった.このとき残業指数は22+22+22=22です.
I/O例#2
n=1の場合、残りの仕事量が[2,1,2]であれば、残業指数を最小化するために1時間働いた結果は[1,1,2]である.残業指数は12+12+22=6です.
ex)
1 3 4 5 7時
9->7=13 4 5 7に減少
7->5=1 3 4 5 5に減少
.
.
これで最後に1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
解題方法は正しいが、タイムアウトした.
問題の説明
会社員のデミはたまに残業しますが、残業すると残業疲労度が溜まります.残業疲労度は、残業開始時の残量に1つの数値を乗じたものです.デミはN時間以内に残業疲労度を最小限に抑える.デミが1時間以内に1時間の仕事量を処理できると言った場合、退勤前の残りのN時間と各仕事の仕事量について、残業疲労度を最低値に下げる関数解を返してください.
せいげんじょうけん
worksは、長さが1より大きく、20000未満の配列です.
worksの要素は50000以下の自然数です.
nは1000000以下の自然数である.
入力例
works = [4, 3, 3] n = 4
works =[2, 1, 2] n = 1
works =[1,1] n = 3
サンプル出力
12
6
0
I/O例説明
I/O例#1
n=4の場合、残りの仕事量が[4,3]の場合、残業指数を最小化するために4時間働いた結果は[2,2,2]であった.このとき残業指数は22+22+22=22です.
I/O例#2
n=1の場合、残りの仕事量が[2,1,2]であれば、残業指数を最小化するために1時間働いた結果は[1,1,2]である.残業指数は12+12+22=6です.
能率の問題を解決する
import java.util.*;
class Solution {
public long solution(int n, int[] works) {
long answer = 0;
int total = Arrays.stream(works).sum();
if(total <= n)
return 0;
Arrays.sort(works);
int index = works.length - 1;
while(index > 0 && n > 0) {
while(works[index] > works[index - 1] && n > 0) {
for(int i = works.length - 1; i >= index && n > 0; i--) {
works[i]--;
n--;
}
}
index--;
}
while(n > 0) {
for(int i = 0; i < works.length; i++) {
works[i]--;
n--;
if(n == 0)
break;
}
}
return Arrays.stream(works).map(i -> i = (int) Math.pow(i, 2)).sum();
}
}
最大から縮小までが近づいてきましたが、優先順位Queueとは思いませんでしたので、このようにパターンに近づきました.ex)
1 3 4 5 7時
9->7=13 4 5 7に減少
7->5=1 3 4 5 5に減少
.
.
これで最後に1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
解題方法は正しいが、タイムアウトした.
priorityQueueの使用ヒントを聞いてから再解釈
import java.util.*;
class Solution {
public long solution(int n, int[] works) {
long answer = 0;
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
Arrays.stream(works).forEach(i -> pq.add(i));
while(!pq.isEmpty() && n > 0) {
int temp = pq.poll();
temp -= 1;
if(temp > 0)
pq.add(temp);
n--;
}
if(n > 0)
return answer;
else {
while(!pq.isEmpty())
answer += (int) Math.pow(pq.poll(), 2);
return answer;
}
}
}
Reference
この問題について(プログラマー-残業指数), 我々は、より多くの情報をここで見つけました https://velog.io/@davidko/프로그래머스-야근-지수テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol