개발/CodingTest

CodingTest - Array(1, 2차원 배열) / 2

잇(IT) 2023. 10. 17. 08:47
728x90
8.
N명의 학생의 국어점수가 입력되면 각 학생의 등수를 입력된 순서대로 출력하는 프로그램을 작성하세요.
같은 점수가 입력될 경우 높은 등수로 동일 처리한다.
즉 가장 높은 점수가 92점인데 92점이 3명 존재하면 1등이 3명이고 그 다음 학생은 4등이 된다.

 

- 방법 1

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public int[] solution(int iNum, int[] ints) {

        int[] answer = new int[iNum];
        int tmp = 1;

        for (int i = 0; i < iNum; i++) {
            for (int j = 0; j < iNum; j++) {
                if (ints[i] < ints[j]) {
                    tmp++;
                }
            }
            answer[i] = tmp;
            tmp = 1;
        }

        return answer;

    }

    public static void main(String[] args) {
        Main main = new Main();
        Scanner scanner = new Scanner(System.in);
        int iNum = scanner.nextInt();
        int[] ints = new int[iNum];
        for (int i = 0; i < iNum; i++) {
            ints[i] = scanner.nextInt();
        }
        for (int x : main.solution(iNum, ints)) {
            System.out.print(x+" ");
        }

    }
}

- 이중 for문을 이용하여 비교하는 문제였다. 사실 등수를 입력하는 부분에서 애를 조금 먹었다...

- 그냥 수를 비교하고 높은 숫자가 있으면 count를 올리고 한 번 순회가 끝나면 다시 count를 0으로 초기화 하는 방식을 사용하면 간단하게 해결되는 문제였다.


9.
5*5 격자판에 아래롸 같이 숫자가 적혀있습니다.

N*N의 격자판이 주어지면 각 행의 합, 각 열의 합, 두 대각선의 합 중 가 장 큰 합을 출력합니다.

 

- 방법 1

import java.util.Scanner;

public class Main {

    public int solution(int iNum, int[][] ints) {

        int answer = 0;
        int sum1, sum2;

        for (int i = 0; i < iNum; i++) {
            sum1 = sum2 = 0;
            for (int j = 0; j < iNum; j++) {
                sum1 += ints[i][j];
                sum2 += ints[j][i];
            }
            answer = Math.max(answer, sum1);
            answer = Math.max(answer, sum2);
        }
        sum1 = sum2 = 0;

        for (int i = 0; i < iNum; i++) {
            sum1 += ints[i][i];
            sum2 += ints[i][iNum - i - 1];
        }
        answer = Math.max(answer, sum1);
        answer = Math.max(answer, sum2);

        return answer;
    }

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

1. 행,열을 합을 구해 최대값을 구하는 for문을 작성하여 값을 비교한다.

2. 대각선 두개를 구해 최대값을 구하는 for문을 작성하여 값을 비교한다.

 

- 크게 어려움은 없었던 문제다.


10.
지도 정보가 N*N 격자판에 주어집니다. 각 격자에는 그 지역의 높이가 쓰여있습니다.
각 격자판의 숫자 중 자신의 상하좌우 숫자보다 큰 숫자는 봉우리 지역입니다. 봉우리 지역이 몇 개 있는 지 알아내는 프로그램을 작성하세요.
격자의 가장자리는 0으로 초기화 되었다고 가정한다.
만약 N=5 이고, 격자판의 숫자가 다음과 같다면 봉우리의 개수는 10개입니다.

 

- 방법 1

import java.util.Scanner;

public class Main {

    public int solution(int iNum, int[][] ints) {

        int answer = 0;
        int[] dx = {0, 1, 0, -1};
        int[] dy = {1, 0, -1, 0};

        for (int i = 0; i < iNum; i++) {
            for (int j = 0; j < iNum; j++) {
                boolean flag = true;
                for (int k = 0; k < 4; k++) {
                    int nx = i + dx[k];
                    int ny = j + dy[k];
                    if (nx >= 0 && nx < iNum && ny >= 0 && ny < iNum && ints[nx][ny] >= ints[i][j]) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    answer++;
                }
            }
        }
        return answer;
    }

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

1. 처음에 단순하게 i + 1, -1 ... 인덱스 위치를 직접 지정하여 크기를 비교하려고 했다

-> 해당 문제점은 테두리에 있는 인데스들의 경우 배열의 범위를 벗어나서 예외가 발생하기 때문에 인덱스를 직접 사용하는 것은 너무 많은 예외 조건을 처리해야 하는 어려움이 있다.

 

2. 기존 위치에 방향에 따른 최종 위치 인덱스에 대한 새로운 변수를 만들어 주는 것이 좋다.

-> 이렇게 되면 최종 인덱스에 대한 조건만 추가해주면 되기 때문에 1. 보다 비교적 적은 예외를 처리하면 된다.

 

- 결국 위 문제까지도 아직은 for문을 통해 비교하는 문제인 것 같아 크게 어려운 것 같지 않다.


11.
김갑동 선생님은 올해 6학년 1반 담임을 맡게 되었다.
김갑동 선생님은 우선 임시로 반장을 정하고 학생들이 서로 친숙해진 후에 정식으로 선거를 통해 반장을 선출하려고 한다.
그는 자기반 학생 중에서 1학년부터 5학년까지 지내오면서 한번이라도 같은 반이었던 사람이 가장 많은 학생을 임시 반장으로 정하려 한다.
그래서 김갑동 선생님은 각 학생들이 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 표를 만들었다.
예를 들어 학생 수가 5명일 때의 표를 살펴보자.

위 경우에 4번 학생을 보면 3번 학생과 2학년 때 같은 반이었고, 3번 학생 및 5번 학생과 3학년 때 같은 반이었으며,
2번 학생과는 4학년 때 같은 반이었음을 알 수 있다. 그러므로 이 학급에서 4번 학생과 한번이라도
같은 반이었던 사람은 2번 학생, 3번 학생과 5번 학생으로 모두 3명이다.
이 예에서 4번 학생이 전체 학생 중에서 같은 반이었던 학생 수가 제일 많으므로 임시 반장이 된다.

 

- 방법 1

import java.util.*;
class Main {
    public int solution(int n, int[][] arr){
        int answer=0, max=0;
        for(int i=1; i<=n; i++){
            int cnt=0;
            for(int j=1; j<=n; j++){
                for(int k=1; k<=5; k++){
                    if(arr[i][k]==arr[j][k]){
                        cnt++;
                        break;
                    }
                }
            }
            if(cnt>max){
                max=cnt;
                answer=i;
            }
        }
        return answer;
    }

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

- 배열을 만들 때 i, j에 대한 의미를 너무 크게 갖지 말고 필요하면 계속해서 변수를 만들어서 문제에서 주어진 객체를 변수화 하여 풀이에 사용해야 할 것 깉다.

- 학년이 정해져있는 것을 그냥 상수로 두고 풀었으면 됐는데... 위의 말과 약간 모순이지만 너무 변수화 하려하지 말자...

 

1. 위 문제는 학생을 위한 반복문 2번 학생의 반을 알아내는데 for문을 1번 총 3번의 for문을 사용해서 풀이하는 문제였다.

2. for문이 많아지는 것에 대해 두려워하지말아야겠다... 근데... for문을 계속 사용하면 어쩔 수 없지만... for문을 계속 많이 사용하는 것이 과연 좋을 것인가라는 생각이 든다...


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

 

- 방법 1

import java.util.Scanner;

public class Main {

    public int solution(int stu, int test, int[][] arr) {

        int answer = 0;

        for (int i = 1; i <= stu; i++) {
            for (int j = 1; j <= stu; j++) {
                int cnt = 0;
                for (int k = 0; k < test; k++) {
                    int pi = 0, pj = 0;
                    for (int s = 0; s < stu; s++) {
                        if(arr[k][s]==i) pi = s;
                        if(arr[k][s]==j) pj = s;
                    }
                    if (pi < pj) {
                        cnt++;
                    }
                    if (cnt == test) {
                        answer++;
                    }
                }
            }
            return answer;
    }

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

- 이번 문제도 기준을 잡는데 시간이 많이 걸린 것이 같다...

 

1. 두 학생을 비교하기 위한 for문을 2개 생성한다.

2. test 결과를 확인하기 위한 for문을 1개 생성하고, 각 학생들을 비교하기 위한 for문을 하나 생성하여, 총 4번의 for문을 생성하게 된다.

 

- 결국 우선 현재까지 문제는 어떻게 문제에 접근하고 풀어가느냐가 중요한 것 같다 별다른 알고리즘이 사용된 것 같지는 않다.

728x90