본문 바로가기
알고리즘/백준

[단계별로 풀어보기-Java] 4단계 1차원 배열

by 꾸주니=^= 2025. 1. 17.

백준 사이트 로고

 

안녕하세요 오늘은 백준 4단계를 푸는 날입니다 ~

확인하러 가보실까요 ~!! 💨 ..


✏️ 문제 번호 : 10807
개수 세기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());

        String[] input = br.readLine().split(" ");
        int[] num = new int[N];
        for (int i = 0; i < N; i++) {
            num[i] = Integer.parseInt(input[i]);
        }

        int v = Integer.parseInt(br.readLine());
        int sum = 0;
        for (int j =0; j < N; j++) {
            if (num[j] == v) {
                sum++;
            }

        }
        System.out.print(sum);
    }
}

 


✏️ 문제 번호 : 10871
X보다 작은 수

 


위 문제를 풀기 전,

수열이란 무엇일까?
수열은 말 그대로 숫자의 나열이다.

 

예제 1 흐름에 대해 설명하자면,

10개의 수열(N)을 입력하고, 정수 5(X)를 입력한다.
수열 A를 이루는 정수 N개를 입력한다.

출력 값은 정수 5(X)보다 작은 수가 출력이 된다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");

        int N = Integer.parseInt(input[0]);
        int X = Integer.parseInt(input[1]);

        String[] ArrayInput = br.readLine().split(" ");
        int[] A = new int[N];
        for (int i = 0; i < N; i++) {
            A[i] = Integer.parseInt(ArrayInput[i]);
        }

        for(int j = 0; j < N; j++){
            if(A[j] < X){
                System.out.print(A[j]+" ");
            }
        }

    }
}

 

주의할 점

수열 입력은 별도로 처리하자!

 


StringBulder를 사용해서
코드 성능 높이기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder(); // 출력 최적화를 위한 StringBuilder 사용
        
        String[] input = br.readLine().split(" ");
        int N = Integer.parseInt(input[0]);
        int X = Integer.parseInt(input[1]);
        
        String[] arrayInput = br.readLine().split(" ");
        
        for (int i = 0; i < N; i++) {
            int num = Integer.parseInt(arrayInput[i]);
            if (num < X) {
                sb.append(num).append(" "); // StringBuilder에 추가
            }
        }
        
        System.out.println(sb.toString().trim()); // StringBuilder에 저장된 결과 출력
    }
}

 

확실히 메모리 성능이 더 좋아진 것을 확인할 수 있다.


✏️ 문제 번호 : 10818
최소, 최대

 


위 코드에서 Math.min(), Math.max()는 배열에서 최소값과 최대값을 구할 수 없다.

그래서 min Integer.MAX_VALUE로, max Integer.MIN_VALUE로 초기화해서 문제를 풀었다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[N];

        String[] input = br.readLine().split(" ");

        // 최소값과 최대값 초기화
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < N; i++) {
            int num = Integer.parseInt(input[i]);
            if (num < min) {
                min = num;
            }
            if (num > max) {
                max = num;
            }
        }

        System.out.println(min + " " + max);
    }
}

 

배열 순회 과정은 다음과 같다.

20: min = 20, max = 20.
10: min = 10, max = 20.
35: min = 10, max = 35.
30: min = 10, max = 35.
7: min = 7, max = 35.

마지막에 저장된 min, max 값을 출력한다.

 


위 문제를 풀다보니, 메모리 성능이 좋지 않게 나왔다.
다른 방법은 뭐가 있을까?

 

StringTokenizer로 입력 처리

StringTokenizer는 split 메서드보다 메모리를 덜 사용하며 빠릅니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        int N = Integer.parseInt(br.readLine());
        
        // 두 번째 입력: N개의 정수를 배열로 저장
        int[] arr = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        
        // 최소값과 최대값 초기화
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        
        // 배열을 순회하며 최소값과 최대값 갱신
        for (int i = 0; i < N; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
            if (arr[i] > max) {
                max = arr[i];
            }
        }

        System.out.println(min + " " + max);
    }
}

 


✏️ 문제 번호 : 2562
최댓값

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        int[] arr = new int[10];
        int max = Integer.MIN_VALUE;

        int index = 0;
        for(int i=1;i<10;i++){
            arr[i]=Integer.parseInt(br.readLine());

            if (arr[i] > max) {
                max = arr[i];
                index = i;
            }

        }
        System.out.print(max + "\n" + index);
    }
}

 


✏️ 문제 번호 : 10810
공 넣기

 


문제 살펴보기

 

📗 입력

바구니 개수 : 1번부터 N번까지 적힌 공 매우 많이 가지고 있음
M개의 행 = M번의 공을 넣다
세 정수 i, j, k
바구니 : i~j
번호 : K번 번호가 적혀져 있는 공

만약, 바구니에 공이 이미 있는 경우에는 들어 있는 공을 빼고, 새로 공을 넣는다.

바구니 개수 :  1~N
공 번호 : 1~N
공 개수 : M

 

📘 출력

1번 바구니부터 N번 바구니에 들어있는 공의 번호를 출력
공이 들어 있지 않은 바구니는 0을 출력

 


예제 1 입력값 풀이

 

1~2번 바구니 : 3번 공 들어감


3~4번 바구니 : 4번 공 들어감


1~4번 바구니 : 1번 공 들어감

바구니 1,2에는 3번 공이 이미 들어가 있고, 
바구니 3,4에는 4번 공이 이미 들어가 있기 때문에 
3,4번 공은 빼준 후, 1번 공을 넣습니다.

 

2번 바구니 : 2번 공 들어감

2번 바구니에 2번 공을 넣어야 하므로, 그전에 있던 1번 공을 빼줍니다.

 

결론


 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 바구니 개수 N과 공 넣는 횟수 M
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        int[] baskets = new int[N];

        for (int t = 0; t < M; t++) {
            st = new StringTokenizer(br.readLine()); // st를 입력받는다. "1 2 3"
            // i와 j는 배열의 인덱스 조정해야 하기 때문에 '-1'해줘야함.
            int i = Integer.parseInt(st.nextToken()) - 1 ; //ex) 문제에서 1번 바구니 → 배열에서 0번 인덱스
            int j = Integer.parseInt(st.nextToken()) - 1; //ex) 문제에서 2번 바구니 → 배열에서 1번 인덱스

            // 이 값은 그대로 배열에 저장되거나 출력되며, 인덱스 조정과는 관련이 없음
            int k = Integer.parseInt(st.nextToken());    // 넣을 공의 번호 3


            // i번부터 j번 바구니까지 k번 공으로 채우기
            for (int idx = i; idx <= j; idx++) {
                baskets[idx] = k;
            }
        }

        // 결과 출력
        StringBuilder sb = new StringBuilder();
        for (int basket : baskets) {
            sb.append(basket).append(" ");
        }
        System.out.println(sb.toString().trim()); //trim(): 불필요한 공백 제거
    }
}

 


✏️ 문제 번호 : 10813
공 바꾸기

 

 


문제 살펴보기

 

📗 입력

바구니 총 N개
각 바구니에는 1번 ~ N번까지 번호 매겨짐
처음에는 바구니와 같은 번호 공이 1개씩 들어가 있음

도현이는 M번 공을 바꾸려고 함
바꿀 바구니 2개 선택(i, j)해서 서로 교환

 

📘 출력

1번 바구니 ~ N번 바구니에 들어 있는 공의 번호 출력

 

위 문제는 i, j끼리 공을 교환한다는게 포인트다!!

공을 교환하기 위해 임시 temp 저장소를 만들어서 공을 교환하자

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 바구니 개수 N과 공 교환 횟수 M
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        // 바구니 번호 매기기
        int[] baskets = new int[N];
        for (int i = 0; i < N; i++) {
            baskets[i] = i + 1;
        }

        for (int t = 0; t < M; t++) {
            st = new StringTokenizer(br.readLine());
            int i = Integer.parseInt(st.nextToken()) - 1;
            int j = Integer.parseInt(st.nextToken()) - 1;

            // i번 바구니와 j번 바구니의 공 교환하기
            int temp = baskets[i];
            baskets[i] = baskets[j];
            baskets[j] = temp;

        }
        
        StringBuilder sb = new StringBuilder();
        for (int basket : baskets) {
            sb.append(basket).append(" ");
        }
        System.out.println(sb.toString().trim()); //trim(): 불필요한 공백 제거
    }
}

 


✏️ 문제 번호 : 5597
과제 안 내신 분 ..?

 


위 문제는 어떻게 접근하면 될지 몰라 gpt한테 물어봤다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 1번부터 30번까지의 학생 상태 (false로 초기화)
        boolean[] submitted = new boolean[31]; // 0번 인덱스는 사용하지 않음

        // 28명의 제출 번호 입력 처리
        for (int i = 0; i < 28; i++) {
            int studentNumber = Integer.parseInt(br.readLine());
            submitted[studentNumber] = true; // 제출한 학생은 true로 표시
        }

        // 제출하지 않은 학생 찾기
        for (int i = 1; i <= 30; i++) {
            if (!submitted[i]) { // false인 학생만 출력
                System.out.println(i);
            }
        }
    }
}

 

코드 설명

1. 학생 배열 초기화

먼저, 1번부터 30번까지의 학생 번호를 다룰 수 있는 크기 31의 boolean 배열을 생성합니다.
이 배열에서 초기값은 모두 false로 설정되며, 배열의 인덱스 1번부터 30번을 사용합니다. 0번 인덱스는 사용하지 않습니다.
예를 들어, submitted[3]은 3번 학생이 과제를 제출했는지를 나타냅니다.

2. 제출한 학생 표시
28명의 제출 학생 번호를 입력받으면서, 입력받은 번호에 해당하는 배열의 값을 true로 변경합니다.
예를 들어, 3번 학생이 제출했다면, submitted[3] = true로 설정합니다.
이렇게 하면 제출 여부를 쉽게 추적할 수 있습니다.

3. 미제출 학생 찾기

배열의 1번부터 30번까지를 순회하며, 값이 false인 경우 해당 번호는 과제를 제출하지 않은 학생 번호입니다.
이 번호를 출력하여 제출하지 않은 학생을 알 수 있습니다.

4. 결과 출력

제출하지 않은 학생 번호를 출력하며, 문제의 조건에 따라 번호는 오름차순으로 출력됩니다. 이는 배열을 1번부터 순차적으로 순회하기 때문에 자연스럽게 오름차순으로 처리됩니다.

 


✏️ 문제 번호 : 3052
나머지

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        boolean[] remainders = new boolean[42]; // 0~41까지의 나머지를 저장
        int count = 0;

        // 입력값 처리
        for (int i = 0; i < 10; i++) {
            int n = Integer.parseInt(br.readLine());
            int remainder = n % 42; // 나머지 계산

            // 나머지가 처음 등장하면 count 증가
            if (!remainders[remainder]) {
                remainders[remainder] = true;
                count++;
            }
        }

        System.out.println(count);
    }
}

 

위 코드도 5597번 문제처럼, boolean을 사용해서
초기 입력 값들은 false고, 나머지가 등장하면 true로 바꿔서 개수를 세는 형태이다.

 


✏️ 문제 번호 : 10811
바구니 뒤집기

 


문제 살펴보기

 

📗 입력

바구니 총 N개, 1번부터 ~ N번
M번 바구니의 순서
(M이 3이면 3개의 바구니 순서를 바꾼다.)
왼쪽부터 i번째 바구니, j번째 바구니의 순서 서로 바꾼다.

입력 형태에 따른 변화는 다음과 같다.

1 2 // 2 1 3 4 5
3 4 // 2 1 4 3 5
1 4 // 3 4 1 2 5
2 2 // 3 4 1 2 5

 

📘 출력

모든 순서를 바꾼 다음, 가장 왼쪽에 있는 바구니부터 순서대로 출력

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 바구니 개수 N과 바꿀 바구니 순서 M
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        // 바구니 번호 매기기
        int[] baskets = new int[N];
        for (int i = 0; i < N; i++) {
            baskets[i] = i + 1;
        }

        for (int t = 0; t < M; t++) {
            st = new StringTokenizer(br.readLine());
            int i = Integer.parseInt(st.nextToken()) - 1;
            int j = Integer.parseInt(st.nextToken()) - 1;

            while(i<j) {
                int temp = baskets[i];
                baskets[i] = baskets[j];
                baskets[j] = temp;
                i++;
                j--;
            }
        }

        StringBuilder sb = new StringBuilder();
        for (int basket : baskets) {
            sb.append(basket).append(" ");
        }
        System.out.println(sb.toString().trim()); //trim(): 불필요한 공백 제거
    }
}

 

코드 설명

위 코드는 i번부터 j번까지 범위를 역순으로 바꿔야합니다.
역순처리는 양 끝을 교환하면서 점진적으로 중앙으로 이동하기에,
while(i<j)문을 사용해서 교환합니다.

i번째와 j번째 값을 교환한 뒤, i는 증가 j는 감소 시킵니다.

 


✏️ 문제 번호 : 1546
평균

 


문제 살펴보기

 

📗 입력

최댓값 : M
모든 점수를 점수 / M * 100 로 고치기
과목 개수 : N

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        String[] input = br.readLine().split(" ");

        double[] scores = new double[N];
        double max = 0;
        for (int i = 0; i < N; i++) {
            scores[i] = Double.parseDouble(input[i]);
            if (scores[i] > max) {
                max = scores[i];
            }
        }
        // 새로운 점수 합 계산
        double sum = 0;
        for (int i = 0; i < N; i++) {
            sum += (scores[i] / max) * 100;
        }
        double newAverage = sum / N;
        System.out.printf("%f", newAverage);
    }
}

 


드디어 4단계 문제 풀이도 끝났습니다 ~~~🫨

끝까지 읽어주셔서 감사하고
저는 다음 5단계 문제 풀이로 돌아오겠습니당 !!!

 

오코완
(오늘도 코테 공부 완료)

인스타그램 : pettydust