[단계별로 풀어보기-Java] 4단계 1차원 배열
안녕하세요 오늘은 백준 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단계 문제 풀이로 돌아오겠습니당 !!!
오코완
(오늘도 코테 공부 완료)