It's going to be one day 🍀

안녕하세요! 매일 매일 공부하려고 노력하는 백엔드 개발자 지망생의 공부 흔적입니다.

코테 준비/백준

[백준] 배열

2jin2 2024. 2. 14. 21:16

10807. 개수 세기

-> 놓친 부분

1) 입력할 때 공백을 기준으로 입력을 받아야해서 StringTokenizer를 사용했는데, 

StringTokenizer st = new StringTokenizer(br.readLine(), " ");

-> 이렇게 선언하고 StringTokenizer를 사용할 때는 

int numbers = Integer.parseInt(st.nextToken());

-> 이렇게 괄호안에 st.nextToken()으로 사용했어야 했다! 괄호안에 br.readLine()을 또 써서 에러가 생겼던 거였음.

 

2) 입력 받은 수를 배열에 넣어줄 때 

arr[i] = Integer.parseInt(st.nextToken());

-> 이렇게하면 바로 넣어줄 수 있음. 별도의 변수 생성하지 않아도됨!

import java.io.*;
import java.util.StringTokenizer;

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

        int number = Integer.parseInt(br.readLine());
        int [] arr = new int[number];
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int find_number = Integer.parseInt(br.readLine());
        int result = 0;
        for (int j = 0; j < arr.length; j++) {
            if (find_number == arr[j]) {
                result ++;
            }
        }
        System.out.println(result);
    }
}

 

10871.X보다 작은 수

-> 놓친 부분

1) 첫 번째 줄 이후에 또 다시 이어지는 추가적인 입력을 받으려면 st 을 다시 초기화해줘야함.

StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int N = Integer.parseInt(st.nextToken());
        int X = Integer.parseInt(st.nextToken());

        int [] arr = new int[N];

        st = new StringTokenizer(br.readLine(), " ");

-> 이후 코드 작성.. 그래야 에러 안남. <NoSuchElementException>

 

2) 추가적으로 String Builder 사용법 정리

String Builder : 비효율적이고 많은 양의 String 객체 사용말고 변경 가능한 문자열 객체를 생성하는 것.

StringBuilder sb = new StringBuilder;
//...//
if (value < X) {
	sb.append(value).append(" ");
    }

-> value가 X보다 작으면 value 값 추가하고 공백도 같이 추가!

 

10810.공 넣기

이 문제는 문제 자체가 엄청 길었다. 그래도 차근차근 로직을 생각해보니 금방 풀렸다.

배열 a부터 b까지 c 숫자의 공으로 채우는 부분 전까진 말이다...

마지막 부분에서 막혔다. 빈 배열을 어떻게 c 숫자로 채우지? 일단 반복문을 사용하는 건 확실했다.

for (int j = a - 1; j < b; j++) {
    basket[j] = c;
}

 

내가 놓친 부분

-> for문 변수 초기화식에 꼭 0이나 1이 올거라는 편견 버리기.. for문으로 범위를 지정할 수 있으니까 j = a-1, j < b를 활용해서 a부터 b까지 선택을 할 수 있는것이다. 

잘 해낸 부분

-> 문제의 말이 복잡해서 당황했지만 차근차근 로직을 생각하며 풀어서 정답에 근접했었다. 정 모르겠으면 손으로라도 그려보기.

 

10813.공 바꾸기

이 문제는 그 전 문제랑 비슷한데 조건만 추가하면 되서 금방 풀었다. 중요한 건 배열의 인덱스값을 서로 바꿔줘야한다는 조건이었다. 그래서

int [] basket = new int [N];
int [] temp = new int [N];

basket을 만들 때 temp도 같이 만들어둔 후 공을 바꿀 때

temp[a-1] = basket[a-1];
basket[a-1] = basket[b-1];
basket[b-1] = temp[a-1];

이렇게 temp에 a를 복사해두고 b에 a를 넣어주었다. 이렇게 값을 서로 변경할 수 있게 되었다. 

-1을 한 이유는 문제에서 주머니의 번호 1번이 인덱스에서는 0번이기 때문이다.

import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        // 생성할 바구니의 크기 N 정하기 (배열의 크기)
        int N = Integer.parseInt(st.nextToken());
        int [] basket = new int [N];
        int [] temp = new int [N];

        // 처음 바구니에 1부터 N 까지 공 넣기
        for (int i = 0; i < basket.length; i++) {
            basket[i] = i+1;
        }

        // 공을 바꿀 횟수 M 정하기 (반복 횟수)
        int M = Integer.parseInt(st.nextToken());
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            // 공을 바꿀 바구니 2개를 선택 (a, b)
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            temp[a-1] = basket[a-1];
            basket[a-1] = basket[b-1];
            basket[b-1] = temp[a-1];
        }
        for (int i = 0; i < basket.length; i++) {
            System.out.print(basket[i]+" ");
        }
        bw.flush();
        bw.close();
        br.close();
    }
}

-> 언젠가 참고할 것 같아서 올려둔 전체풀이코드 

 

5597.과제 안 내신 분..?

이 문제의 핵심은

1) 학생들의 bool 타입 배열을 선언한 후 문제에서 받은 입력을 입력하면서 해당 배열 위치를 true로 바꿔주고

2) false인 나머지 숫자들을 출력하는 것이다.

실제 구현은 어렵지 않지만 딱 "boolean 타입 배열" 이라는 핵심이 생각안나서 좀 오래걸렸다.

// 모든 학생들에게 bool 타입으로 false 값 부여 (30명)
boolean [] students = new boolean[31];
for (int i = 0; i < 28; i++) {
    int n = Integer.parseInt(br.readLine());
    students[n] = true;
}

for (int j = 1; j <= 30; j++) {
    if (!students[j]) {
        System.out.println(j);
    }
}

-> 1~30 크기의 students boolean 배열을 선언하고 28명의 번호를 28번 반복하면서 해당 위치 배열값은 true로 지정한다.

-> 1부터 30 까지의 배열을 돌면서 false 인 경우만 출력한다.

 

3052.나머지

이 문제의 핵심은 바로 위 문제와 마찬가지로 boolean 배열을 선언하는 것이다.

- n번째와 n+1 번째를 비교해야한다는 것과 if 조건문까진 작성했는데 그 이상 생각하질 못했다..

import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        int[] arr = new int [10];
        boolean bl; // n번째와 n+1번째를 비교하기 위한 변수
        int count = 0;

        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(br.readLine()) % 42;
        }
        for (int i = 0; i < 10; i++) {
            bl = false; // 기본값을 false로 설정
            for (int j = i+1; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    bl = true;
                    break;
                }
            }
            if (bl == false) {
                count ++;
            }
        }
        System.out.println(count);

        bw.flush();
        bw.close();
        br.close();
    }

}

-> 먼저 숫자 10개를 입력받는것이 명시되어있으므로 arr 배열의 크기를 지정해준다.

- 그리고 숫자를 입력받을 때 arr[i]에 바로 입력받고 바로 42로 나눠주었다.

- 그리고 위에서 정의한 boolean 변수의 기본값을 false로 설정하고,

- 이중 for문에 넣은 후 arr[i] == arr[j] 일 때 (배열의 값이 같을 때) 를 true 처리해주었다.

(두번째 for문은 그 다음 배열의 값과 비교해야하기 때문에 0이 아닌 i+1부터 시작하였다.)

- 그리고 마지막에 false인 것들을 세며 (배열의 값이 같지 않을 때 = 서로 다른 나머지) count++를 해주었다.

 

일단 boolean 사용을 잘 생각하지못했고, 이중 for문에서 두 번째 for문의 시작을 i+1로 해야된다는 것을 생각하지 못했다.

다음부터는 2가지 비교문제시 boolean 사용 방법을 꼭 미리 생각해봐야겠다.

10811.바구니 뒤집기

이 문제는 배열을 뒤집어야하는 문제였는데, 배열을 뒤집는 로직이 머릿속으로는 생각이 안되서 직접 글로 작성했다.

직접 손으로 적어보며 코드를 짜니까

1) 내가 원래 생각했던 것처럼 basket이 for문 실행마다 12345로 초기화되지 않고 이어진다는 사실을 알게됐다.

2) 특히 3번째 값을 넣을 때 1번 공부터 4번 공을 전부 뒤집어주어야된다는 사실이 while 문 아이디어를 생각하게했고 결국 문제를 풀어내게 되었다! 다음에도 복잡하거나 막히는 부분이 있으면 직접 손으로 작성해봐야겠다.

// 공을 뒤집을 숫자 2개를 선택 (i, j)
            int i = Integer.parseInt(st.nextToken());
            int j = Integer.parseInt(st.nextToken());

            while (i < j) {
                temp[0] = basket[j-1];
                basket[j-1] = basket[i-1];
                basket[i-1] = temp[0];
                i++;
                j--;
            }

-> 공을 뒤집는 중요 로직

 

 

'코테 준비 > 백준' 카테고리의 다른 글

[백준] 정렬  (0) 2024.04.22
[백준] 스택과 큐  (1) 2024.04.18
[백준] 반복문  (0) 2024.01.24
[백준] 조건문  (0) 2024.01.22
[백준] 입출력과 사칙연산 중요 내용  (0) 2024.01.18