プログラマコード問題2010/11/26-Lv.1ジャージ


[質問]


昼食の時間に盗まれ、一部の学生の運動服が盗まれた.幸いなことに、余分な運動服を貸したい学生がいます.学生の番号は体格順で、前の番号の学生か後ろの番号の学生の運動服しか貸せません.例えば、4番の学生は3番か5番の学生にしか運動服を貸すことができません.運動服がないと授業を受けられないので、適当に運動服を借りて、できるだけ多くの学生に体育の授業をさせなければなりません.
すべての学生の数n,ジャージを盗まれた学生の番号の並びloss,複数のジャージを持った学生の番号の並びreserveをパラメータとした場合,解関数を書いて体育の授業を受けられる学生の最上位値を返してください.
せいげんじょうけん
全生徒数は2名以上30名以下である.
運動服を盗まれた生徒数は1名以上n名以下で、重複番号はない.
複数のユニホームを着用した生徒数は1名以上n名以下であり,重複番号はない.
余分な運動服を持っている学生だけが他の学生に運動服を貸すことができる.
複数の運動服を持ってきた学生は、運動服が盗まれたのかもしれない.このとき、この学生は1枚の運動服だけが盗まれたと仮定し、1枚の運動服しか残っていないため、他の学生に運動服を貸すことができない.
I/O例
n
lost
reserve
return
5
[2, 4]
[1, 3, 5]
5
5
[2, 4]
[3]
4
3
[3]
[1]
2
I/O例説明
例1
1番学生は運動服を2番学生に貸し、3番学生または5番学生は運動服を4番学生に貸し、5人は体育の授業を受けることができる.
例2
3番の学生は運動服を2番の学生か4番の学生に貸して、4人の学生は体育の授業を受けることができます.

[回答]

function solution(n, lost, reserve) {
  const students = new Array(n).fill(1);
  lost.forEach(studentNum => students[studentNum - 1] = 0);
   
  for(let i = reserve.length - 1; i >= 0; i--) {
    if(!(students[reserve[i] - 1])) {
      students[reserve[i] - 1] = 1;
      reserve.splice(i, 1);
    }
  }
   
  for(let i = reserve.length - 1; i >= 0; i--) {
    if(students[reserve[i]] === 0) {
      students[reserve[i]] = 1;
      reserve.splice(i, 1);
    }
    else if(students[reserve[i] - 2] === 0) {
      students[reserve[i] - 2] = 1;
      reserve.splice(i, 1);
    }
  }
   
  return students.filter(student => student === 1).length;
}
まず、学生数に等しい長さの配列を作成し、1で埋めます.
そしてlostの並びを確認し、その生徒だけが0にします.
それから複文を利用して、まずreserveの中にいますが、0の学生はまず1に変えて、自分を基準にして、両側に運動服がない学生を見つけて、それを1に変えます.
次いで、students配列において1lengthreturnのみが見出された.