[알고리즘]완전탐색:멘토링

chaewon Im·2022년 1월 26일
0
post-thumbnail

어려워서 오래 고민한 문제...강의 풀이방법을 먼저 보고 이를 코드화 시켜서 겨우 이해했다.

4-3.멘토링

📃 문제

현수네 반 선생님은 반 학생들의 수학 점수를 향상시키기 위해 멘토링 시스템을 만들려고 합니다.
멘토링은 멘토(도와주는 학생)과 멘티(도움을 받는 학생)가 한 짝이 되어 멘토가 멘티의 수학공부를 도와주는 것입니다.
선생님은 M번의 수학테스트 등수를 가지고 멘토와 멘티를 정합니다.
만약 A학생이 멘토이고 B학생이 멘티가 되는 짝이 되었다면, A학생은 M번의 수학테스트에서 모두 B보다 등수가 앞서야 합니다.
M번의 수학성적이 주어지면 멘토와 멘티가 되는 짝을 만들 수 있는 경우가 총 몇가지 인지 출력하는 프로그램을 작성하세요.

[입력설명]
첫번째 줄에 반 학생수 N(1<=N<=20)과 M(1<=M<=10)이 주어진다.
두번째 줄부터 M개의 줄에 걸쳐 수학테스트 결과가 학생 번호로 주어진다. 학생번호가 제일 앞에서부터 1등,2등..N등 순으로 표현된다.
만약 한 줄에 N=4이고, 테스트 결과가 3 4 1 2로 입력되었다면 3번 학생이 1등, 4번 학생이 2등, 1번 학생이 3등, 2번 학생이 4등을 의미합니다.

[출력설명]
짝을 만들 수 있는 총 경우를 출력합니다.

[입력 예제]
4 3
3 4 1 2
4 3 2 1
3 1 4 2

[출력 예제]
3


✏️ 풀이

학생별로 짝지을 수 있는 모든 경우의 수를 탐색해야 한다.(학생이 4명이면 4*4)
이를 멘토 학생을 i,멘티 학생을 j로 두고 이중 for문으로 탐색한다.(for i..for j...)

다음으로 주어진 수학테스트 결과를 탐색하며 i학생과 j학생 각각의 등수를 확인한다.
수학테스트 배열에서 열의 인덱스가 등수를 가리키니,수학테스트 열의 값이 i,j와 일치하면 각각의 인덱스가 i,j학생들의 등수가 된다. (이 때 등수는 탐색을 위해 0등부터 3등으로 설정.)
ex)2번째 위치한 값이 i와 같다면 i는 2등

이렇게 m개의 수학 테스트 결과를 확인하면서 만약 i가 j보다 등수가 높다면 그 때마다 카운트 변수(cnt)를 ++시킨다.

모든 테스트에서 i가 높은 결과를 가졌다면 cnt 값은 m과 일치할 것이다. 따라서 만약 cnt 변수가 m과 같다면 멘토 멘티 짝을 이룰 수 있는 경우이므로 answer를 ++한다.


이건 i=1,j=2로 가정했을 때의 동작을 그려본 (나만 알아볼 수 있는)그림이다.
s를 돌면서 1을 만나면 i의 등수가 s가 되고, 2를 만나면 j의 등수가 s가 되는것이다. 그리고 i의 등수가 j의 등수보다 높은 등수이면 cnt를 ++하는데, 그림에서는 m2에서 j가 i보다 높은 등수를 가졌으므로 이 때 cnt값이 올라가지 않고, t를 다 돌았을 때 cnt는 3이 아닌 2가 된다. 이렇게 되면 짝을 이룰 수 있는 케이스가 아니므로 answer도 ++되지 않는다.

💡 풀다가 놓친 것!!

  • 구현 단계에서 i,j등수 비교 시 i등수가 j등수보다 작아야 한다ㅋㅋㅋㅋㅋ 등수는 작을수록 높으니까..!
if(score_i<score_j) //이걸 score_i>score_j 라고 해놓고 결과가 왜이러나 했다ㅋㅋㅋㅋ
  • 학생 번호가 1부터 시작하니까 i,j는 1부터 시작해야 한다.
    (test배열은 0부터 시작해야 인덱스 순회 가능한거 맞음.)
function solution(n,m,test){
    let answer = 0
    let tmp = [] //결과 확인 용도
    for(let i=1;i<=n;i++){
        for(let j=1;j<=n;j++){
            let cnt = 0
            for(let t=0;t<m;t++){
                let score_i = score_j = 0
                for(let s=0;s<n;s++){
                    if(test[t][s]===i) score_i = s
                    if(test[t][s]===j)score_j = s
                }
                if(score_i<score_j){ //i의 등수가 작아야 함.
                    console.log('멘토:',i,'점수:',score_i)
                    console.log('멘티:',j,'점수:',score_j)
                    console.log('========================')
                    cnt+=1
                }
            }
            if(cnt == m){
                tmp.push([i,j])//멘토-멘티 짝 확인하기
                answer++
            }
        }
    }
    console.log(tmp)
    return answer
}

let n = 4
let m = 3
let num = [[3,4,1,2],[4,3,2,1],[3,1,4,2]]
console.log(solution(n,m,num))
profile
빙글빙글 FE 개발자

0개의 댓글