[c++] ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ :: 체윑볡 (문제 풀이, μ½”λ“œ)

체윑볡

https://programmers.co.kr/learn/courses/30/lessons/42862#

문제

문제 μ„€λͺ…

μ μ‹¬μ‹œκ°„μ— 도둑이 λ“€μ–΄, 일뢀 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆ μ—¬λ²Œ 체윑볡이 μžˆλŠ” 학생이 μ΄λ“€μ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주렀 ν•©λ‹ˆλ‹€. ν•™μƒλ“€μ˜ λ²ˆν˜ΈλŠ” 체격 순으둜 맀겨져 μžˆμ–΄, λ°”λ‘œ μ•žλ²ˆν˜Έμ˜ ν•™μƒμ΄λ‚˜ λ°”λ‘œ λ’·λ²ˆν˜Έμ˜ ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 4번 학생은 3번 ν•™μƒμ΄λ‚˜ 5번 ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 체윑볡이 μ—†μœΌλ©΄ μˆ˜μ—…μ„ 듀을 수 μ—†κΈ° λ•Œλ¬Έμ— μ²΄μœ‘λ³΅μ„ 적절히 빌렀 μ΅œλŒ€ν•œ λ§Žμ€ 학생이 μ²΄μœ‘μˆ˜μ—…μ„ λ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

전체 ν•™μƒμ˜ 수 n, μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ lost, μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ reserveκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μ²΄μœ‘μˆ˜μ—…μ„ 듀을 수 μžˆλŠ” ν•™μƒμ˜ μ΅œλŒ“κ°’μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”.

 

μ œν•œμ‚¬ν•­

  • 전체 ν•™μƒμ˜ μˆ˜λŠ” 2λͺ… 이상 30λͺ… μ΄ν•˜μž…λ‹ˆλ‹€.
  • μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ 체윑볡이 μžˆλŠ” ν•™μƒλ§Œ λ‹€λ₯Έ ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ•Œ 이 학생은 μ²΄μœ‘λ³΅μ„ ν•˜λ‚˜λ§Œ λ„λ‚œλ‹Ήν–ˆλ‹€κ³  κ°€μ •ν•˜λ©°, 남은 체윑볡이 ν•˜λ‚˜μ΄κΈ°μ— λ‹€λ₯Έ ν•™μƒμ—κ²ŒλŠ” μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μ—†μŠ΅λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예

n lost reserve return
5 [2, 4] [1, 3, 5] 5
5 [2, 4] [3] 4
3 [3] [1] 2

 

μž…μΆœλ ₯ 예 μ„€λͺ…

예제 #1
1번 학생이 2번 ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주고, 3번 ν•™μƒμ΄λ‚˜ 5번 학생이 4번 ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주면 학생 5λͺ…이 μ²΄μœ‘μˆ˜μ—…μ„ 듀을 수 μžˆμŠ΅λ‹ˆλ‹€.

 

예제 #2
3번 학생이 2번 ν•™μƒμ΄λ‚˜ 4번 ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주면 학생 4λͺ…이 μ²΄μœ‘μˆ˜μ—…μ„ 듀을 수 μžˆμŠ΅λ‹ˆλ‹€.

 


μ½”λ“œ

  1. μ–΄λ ΅κ²Œ μƒκ°ν•œ 풀이 (톡과 x)
#include <string>
#include <vector>

using namespace std;

int getSuit(vector<int>& lost, vector<int> reserve, int attempt){
    if(attempt>=lost.size()) // λͺ¨λ“  lost 학생을 λ‹€ κ³ λ €ν–ˆμ„ λ•Œ
        return reserve.size();
    if(reserve.size()==0) // λͺ¨λ“  reserve 학생이 μ²΄μœ‘λ³΅μ„ λ‹€ λΉŒλ €μ€¬μ„ λ•Œ
        return 0;

    int reserve_num = reserve.size();
    int lost_num = lost[attempt]; // μ²΄μœ‘λ³΅μ„ μ°Ύμ•„μ€˜μ•Όν•˜λŠ” 학생

    int flag =0;
    for(int i=0; i<reserve.size(); i++){
        auto pos = reserve.begin()+i;
        if(reserve[i]==lost_num-1){ // reserveκ°€ 있으면 reserveμ—μ„œ μ—†μ•€ ν›„ μž¬κ·€ 호좜
            reserve.erase(pos);
            int tmp = getSuit(lost, reserve, attempt+1);
            reserve.insert(pos, lost_num-1);
            if(reserve_num > tmp)
                reserve_num = tmp;
            flag =1;
        }else if(reserve[i]==lost_num+1){
            reserve.erase(pos);
            int tmp = getSuit(lost, reserve, attempt+1);
            reserve.insert(pos, lost_num+1);
            if(reserve_num > tmp)
                reserve_num = tmp;
            flag =1;
        }
    }
    if(flag==0){ // λ§žλŠ” reserveκ°€ μ—†μŒ
        int tmp = getSuit(lost, reserve, attempt+1); // λ‹€λ₯Έ lost 학생 체윑볡 μ°Ύμ•„μ£ΌκΈ°
        if(reserve_num > tmp)
            reserve_num = tmp;
    }

    return reserve_num;
}

int solution(int n, vector<int> lost, vector<int> reserve) {
    int answer = 0;
    int num_of_give = reserve.size()-getSuit(lost, reserve, 0);
    int num_of_left_lost = lost.size()-num_of_give;
    answer = n-num_of_left_lost;

    return answer;
}

쑰건을 μ°Ύμ•„μ„œ μž¬κ·€λ‘œ ν‘ΈλŠ” 방식

 

  1. μ‰½κ²Œ μƒκ°ν•œ 풀이 (톡과o)
#include <string>
#include <vector>

using namespace std;

int solution(int n, vector<int> lost, vector<int> reserve) {
    int answer = 0;
    int size = lost.size();
    int r_size = reserve.size();
    int count = 0; // lost 쀑 μ²΄μœ‘λ³΅μ„ 얻은 학생 수

    for(int i=0; i<size; i++){
        for(int j=0; j<r_size; j++){
            if(lost[i]==reserve[j]) { // λ„λ‚œλ‹Ήν•œ 학생 == μ—¬λ²Œ 체윑볡 학생
                count++;
                lost[i]=-1;
                reserve[j]=-1;
                break;
            }
        }
    }

    for(int i=0; i<size; i++){
        if(lost[i]==-1) // 이미 μ²΄μœ‘λ³΅μ„ 얻은 아이이면
            continue;
        for(int j=0; j<r_size; j++){
            if(lost[i]+1 == reserve[j] || lost[i]-1 == reserve[j]){
                reserve[j]=-1;
                // lost[i]=-1;
                count++;
                break;
            }
        }
    }

    answer = n-size+count;

    return answer;
}

 

풀이

μ΄λ ‡κ²Œ μž…λ ₯의 λ²”μœ„κ°€ μž‘μ€ λ¬Έμ œλŠ” κ·Έλƒ₯ λΉ λ₯΄κ²Œ μ™„μ „νƒμƒ‰μœΌλ‘œ ν’€μ–΄μ•Όν•œλ‹€. μœ„μ˜ κ°„λ‹¨ν•œ 풀이라고 적어둔 것도 λ‹€λ₯Έ μ‚¬λžŒμ˜ 풀이λ₯Ό λ³΄λ‹ˆ 사싀은 λ³΅μž‘λ„κ°€ 높은 ν’€μ΄μ˜€λ‹€.

 

κ°„λ‹¨ν•œ ν’€μ΄λŠ” student 배열을 λ§Œλ“€μ–΄ lost에 ν•΄λ‹Ήν•˜λŠ” 학생은 -1, reserve에 ν•΄λ‹Ήν•˜λŠ” 학생은 +1 ν•œ ν›„, -1인 ν•™μƒλ“€λ§Œ μ£Όμœ„μ— 1인 학생이 μžˆλŠ”μ§€ 봐주면 λ˜λŠ” 식이닀. μ΄λ ‡κ²Œ ν’€λ©΄ O(n)λ§Œμ— ν’€ 수 μžˆλ‹€.

 

κ°„λ‹¨ν•œ 문제일 수둝 λ³΅μž‘ν•˜κ²Œ μƒκ°ν•΄μ„œ 더 μ–΄λ €μš΄ 것 κ°™λ‹€..! μž…λ ₯의 μˆ˜κ°€ μž‘μœΌλ©΄ Greedy. κΈ°μ–΅ν•˜μž.

λ°˜μ‘ν˜•