スポーツウェア


問題の説明


昼食の時間に盗まれ、一部の学生の運動服が盗まれた.幸いなことに、余分な運動服を貸したい学生がいます.学生の番号は体格順で、前の学生か後ろの学生の運動服しか貸せません.例えば、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

    私のコメント(JAVA)

  • の残りの学生のうち、スポーツウェアを盗んだ学生は貸すことができず、先に処理した.
  • の前の番号から借りてこそ、最大限に多く借りることができます.
  • import java.util.Arrays;
    
    class Solution {
        public int solution(int n, int[] lost, int[] reserve) {
            Arrays.sort(lost);
            Arrays.sort(reserve);
            
            // 여분이 있는 학생 중 도난당한 학생은 체육복을 빌려줄 수 없다.
            for (int i=0; i<reserve.length; i++) {
                for (int j=0; j<lost.length; j++) {
                    if (reserve[i] == lost[j]) {
                        reserve[i] = 0;
                        lost[j] = 0;
                        break;
                    }
                }
            }
            
            // 학생 수 계산
            int cnt = 0;
            for (int l=0; l<lost.length; l++) {
                if (lost[l] == 0) continue;
                
                for (int r=0; r<reserve.length; r++) {
                    if (reserve[r] == 0) continue;
                    
                    if (reserve[r] == lost[l]-1) {
                        reserve[r] = 0;
                        lost[l] = 0;
                        break;
                    } else if (reserve[r] == lost[l]+1) {
                        reserve[r] = 0;
                        lost[l] = 0;
                        break;
                    }
                }
                
                if (lost[l] != 0) {
                    cnt++;
                }
            }
            
            return n-cnt;
        }
    }

    他の人の解答(JAVA)

    class Solution {
        public int solution(int n, int[] lost, int[] reserve) {
            int[] people = new int[n];
            int answer = n;
            
            // 체육복이 없는 번호(0부터 시작)는 음수이고 있으면 0 보다 큰 수이다.
            for (int l : lost) {
                people[l-1]--;
            }
            for (int r : reserve) {
                people[r-1]++;
            }
            
            for (int i=0; i<people.length; i++) {
                // 해당 번호가 -1인 경우(체육복이 없는 경우)
                if (people[i] == -1) {
                    // 이전 번호가 있고, 이전 번호가 체육복이 있는 경우
                    if (i-1 >= 0 && people[i-1] == 1) {
                        // 해당 번호를 + 처리하고 체육복을 빌려준 사람의 번호를 - 처리
                        people[i]++;
                        people[i-1]--;
                    
                    // 다음 번호가 있고, 다음 번호가 체육복이 있는 경우
                    } else if (i+1<people.length && people[i+1] == 1) {
                        // 해당 번호를 + 처리하고 체육복을 빌려준 사람의 번호를 - 처리
                        people[i]++;
                        people[i+1]--;
                    } else {
                        // 체육복을 빌려줄 이전or다음 번호가 없는 경우 학생수 빼기
                        answer--;
                    }
                }
            }
                
            return answer;
        }
    }

    私の解答(JavaScript)

    function solution(n, lost, reserve) {
      // 여분 체육복이 도난당한 학생 먼저 배열에서 제거
      const arr = lost.filter(a => reserve.includes(a));
      lost = lost.filter(a => !arr.includes(a));
      reserve = reserve.filter(a => !arr.includes(a));
      
      lost.sort((a,b) => a-b);
      reserve.sort((a,b) => a-b);
      
      let cnt = 0;
      for (let i=0; i<lost.length; i++) {
        for (let j=0; j<reserve.length; j++) {
          if (reserve[j] === lost[i]-1) {
            reserve.splice(j, 1);
            lost[i] = 0; // lost 배열의 요소를 splice 하면 index가 바뀐다..
            break;
          } else if (reserve[j] === lost[i]+1) {
            reserve.splice(j, 1);
            lost[i] = 0;
            break;
          }
        }
        
        if (lost[i] != 0) {
          cnt++;
        }
      }
      
      return n-cnt;
    }

    他の人の解答(JavaScript)

    function solution(n, lost, reserve) {
      // 여분 체육복이 도난당한 학생 먼저 배열에서 제거
      const realReserve = reserve.filter(r => !lost.includes(r));
      const realLost = lost.filter(r => !reserve.includes(r));
      
      const ableNum = realLost.filter(a => {
        // 체육복을 빌려줄 수 있으면 realReserve에서 그 요소를 제거하고 true 리턴
        return realReserve.find((b, i) => {
          const has = (b === a-1) || (b === a+1);
          if (has) {
            delete realReserve[i];
          }
          return has;
        });
      }).length; // lost에서 체육복을 빌릴 수 있는 학생의 수
      
      // 전체 학생 수에서 (체육복이 없는 학생수 - 체육복을 빌린 학생수) 만큼 뺀다.
      return n - (realLost.length - ableNum);