본문 바로가기

Java/Java 알고리즘 인프런

[Ch.02 - Array] 12. 멘토링

반응형
12. 멘토링
 

설명

현수네 반 선생님은 반 학생들의 수학점수를 향상시키기 위해 멘토링 시스템을 만들려고 합니다.

멘토링은 멘토(도와주는 학생)와 멘티(도움을 받는 학생)가 한 짝이 되어 멘토가 멘티의 수학공부를 도와주는 것입니다.

선생님은 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등을 의미합니다.

출력

첫 번째 줄에 짝을 만들 수 있는 총 경우를 출력합니다.

 

예시 입력 1 

4 3
3 4 1 2
4 3 2 1
3 1 4 2

예시 출력 1

3

두 번째 줄부터 M개의 줄에 걸쳐 수학테스트 결과가 학생번호로 주어진다.

학생번호가 제일 앞에서부터 1등, 2등, ...N등 순으로 표현된다.

 

4중For문 수행: n은 학생수, m은 테스트수

  1. 멘토 -> for(int i=1; i<=n; i++)
  2. 멘티 -> for(int j=1; j<=n; j++)
  3. 테스트 -> for(int k=0; k<m; k++)
  4. 등수 -> for(int s=0; s<n;s++)

4중 for문 수행하면서, 변수값 초기화 및 계산 위치

  1. 멘토
  2. 멘티 
  3. 테스트마다 cnt 수 초기화
  4. 테스트
  5. 각각 등수 초기화
  6. 등수
  7. 등수 찾기 -> arr[k][s]
  8. 등수 크기 비교 후, cnt++;
  9. 테스트 반복이 끝나면, if(cnt==m) 확인

 

package algo2;

import java.util.Scanner;

public class Test12 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int m = in.nextInt();
		int[][] arr = new int[m][n];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				arr[i][j] = in.nextInt();
			}
		}
		System.out.println(solution(n, m, arr));
	}

	static int solution(int n, int m, int[][] arr) {
		// 3412 -> 1등 3번, 2등 4번, 3등 1번, 4등 2번순
		int answer = 0;
		// 멘토 i 멘티 j, 테스트 l, 등수 h
		// 테스트l번의 등수h가 i이고, j인걸 확인
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				boolean flag = true;

				for (int l = 0; l < m; l++) {
					int i1 = 0;
					int i2 = 0;

					for (int h = 0; h < n; h++) {
						if (arr[l][h] == i) {
							i1 = h;
						}
						if (arr[l][h] == j) {
							i2 = h;
						}
					}
					if (i1 >= i2) {
						flag = false;
						break;
					}
				}
				if (flag) {
					// System.out.println("멘토"+i+" "+"멘티"+j);
					answer++;
				}
			}
		}
		return answer;
	}
}

 

 

+) 세련된 풀이

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
//배열 reverseOrder

public class Main {
	public int solution(int[][] arr, int n, int m) {
		int answer = 0;
		int cnt = 0;
		for (int i = 1; i <= n; i++) {
			// 멘토
			for (int j = 1; j <= n; j++) {
				// 멘티
				cnt = 0;
				// 테스트 마다 cnt를 초기화해야 하므로
				for (int k = 0; k < m; k++) {
					// 테스트
					int pi = 0;
					int pj = 0;
					// 등수를 설정하기전 초기화
					for (int s = 0; s < n; s++) {
						// 등수
						if (arr[k][s] == i) {
							pi = s;
						}
						if (arr[k][s] == j) {
							pj = s;
						}

					}

					if (pi < pj)
						cnt++;

				}
				//테스트 끝나고 나서 -> cnt 확인
				if (cnt == m)
					answer++;

			}

		}

		return answer;

	}

	public static void main(String[] args) {
		Main T = new Main();
		Scanner kb = new Scanner(System.in);
		int n = kb.nextInt();
		int m = kb.nextInt();
		int[][] arr = new int[m][n];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				arr[i][j] = kb.nextInt();
			}
		}
		System.out.println(T.solution(arr, n, m));

	}
}

 

 


#테스트 수 마다 비교하는 방법

-> 각 테스트마다 등수가 다르기 때문에, 테스트수만큼 도는 for문에서 등수 변수를 초기화 해야한다.

 

1. 테스트 수와 등수를 비교한 변수가 같은지 확인

    if (pi < pj)
        cnt++;

}
//테스트 끝나고 나서 -> cnt 확인
if (cnt == m)
    answer++;

2. flag변수를 이용

    if (i1 >= i2) {
        flag = false;
        break;
    }
}
if (flag) {
    // System.out.println("멘토"+i+" "+"멘티"+j);
    answer++;
}

 

 


(1) m: 학생수

(2) n: 시험수

(3) arr[n][m]으로 배열 생성

(4) 성적표 만들기 : result[m+1][m+1] 배열 -> 학생번호를 1번부터 주기 때문에

(5) 순서대로 등수 : 1등은 3번, 2등은 4번, 3등은 1번, 4등은 2번

-> 해당 칼럼이 성적표의 멘토 번호로 지정하고, 나머지 등수를 멘티로 설정

-> result[arr[k][i]][arr[k][j]]

 

 

import java.util.Scanner;
  
public class Main {
  public static void main(String[] args){
    Scanner in=new Scanner(System.in);

    int m = in.nextInt();
    int n = in.nextInt();
    int[][] arr = new int[n][m+1];
    for(int i=0;i<n;i++){
      for(int j=1;j<=m;j++){
        //3번이 1등 4번이 2등 1번이 3등 2번이 4등
        arr[i][j]=in.nextInt();
      }
    }
    System.out.println(solution(n,m,arr));
  }
  static int solution(int n, int m, int[][]arr){
    //n번의 시험 m명의 학생
    int answer=0;
    //멘토 멘티 성적표
    int[][] result = new int[m+1][m+1];
    //시험
    for(int k=0;k<n;k++){
    //멘토
    for(int i=1;i<=m;i++){
      //멘티
      for(int j=i+1;j<=m;j++){
          //1등이 3번, 2등이 4번, 3등이 1번, ,4등이 2번
          // if(arr[k][i]arr[k][j]){
            result[arr[k][i]][arr[k][j]]+=1;
          }
        }
      }
    for(int i=1;i<=m;i++){
      for(int j=1;j<=m;j++){
        if(result[i][j]==n) answer++;
      }
    }
    return answer;
  }
}

import java.util.Scanner;
  
public class Main {
  public static void main(String[] args){
    Scanner in=new Scanner(System.in);
    //학생 수 n
    //테스트 횟수 m
    int n = in.nextInt();
    int m = in.nextInt();
    int[][] arr=new int[m][n];
    for(int i=0;i<m;i++){
      for(int j=0;j<n;j++){
        arr[i][j]=in.nextInt();
      }
    }
    //학생번호가 값, 등수가 인덱스
    int answer=0;
    int[][] result=new int[n+1][n+1];
    //테스트
    for(int i=0;i<m;i++){
      //등수
      for(int j=0; j<n;j++){
        int tmp=arr[i][j];
        //3
        //학생 번호
        for(int k=j+1; k<n; k++){
          //[3][4]
          result[tmp][arr[i][k]]+=1;
          //result==m이어야 짝이 가능
          if(result[tmp][arr[i][k]]==m) answer++;
        }
      }
    }
    System.out.println(answer);
  }
}
반응형