본문 바로가기
활동정리/모각코

모각코 2회차 활동 내용 정리

by 잔디🌿 2023. 7. 15.

    2023.7.14 모각코 2회차 목표 

    백준 알고리즘 문제 풀고 블로그에 정리하기

     

    https://ethereal-coder.tistory.com/48

     

    백준 [자바 java] 14719 : 빗물

    https://www.acmicpc.net/problem/14719 14719번: 빗물 첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H

    ethereal-coder.tistory.com

    https://www.acmicpc.net/problem/14719

     

    14719번: 빗물

    첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치

    www.acmicpc.net

     

    풀 문제 찾다가 우리학교 문제 발견해서 풀어봤어요.

    처음 양 옆에가 벽인 것만 물을 채웠는데 그럼 절대 안되더라구요.

    그래서 for문을 이용해서 가로로 한 줄씩 왼쪽부터 탐색하면서 벽이 나오면 다음 벽이 나올 때까지 세고.. 뭐 이런 알고리즘을 생각했는데 너무너무 복잡했어요.

    생각해보니까 아래부터 가로로 한 줄씩 벽 사이의 간격을 재면 되더라구요!
    그래서 stack을 이용해서 벽이 있는 곳의 위치를 넣고 차례로 빼서 간격을 세어주었답니다.

    근데 제 코드에 한가지 문제점이 있는데, 제가 수를 입력받고 배열을 벽으로 채우는 과정에서 뭔가 잘못했는지 웅덩이가 뒤집어진(?) 형태가 되어버렸어요. 근데 문제푸는데 지장은 없어서(어차피 한 줄씩 보니까) 그냥 풀었습니다!

     

     

     

    풀이코드

     

    import java.util.*;
    import java.io.*;
    import java.math.*;
    
    
    public class Main {
    
    
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(br.readLine());
    
            int n = Integer.parseInt(st.nextToken());
            int m = Integer.parseInt(st.nextToken());
    
            int arr[][] = new int[n][m];
    
            st = new StringTokenizer(br.readLine());
    
            for(int i = 0;i<m;i++){
                int k = Integer.parseInt(st.nextToken());
    
                for(int j = k-1 ;j>=0;j--){
                    arr[j][i] = 1;
                }
            }
    
            
    
            int ans = 0;
    
            Stack<Integer> s = new Stack<>();
    
            for(int i = 0;i<n;i++){
                for(int j = 0;j<m;j++){
                    if(arr[i][j] == 1){
                        s.push(j);
                    }
                }
    
                if(s.isEmpty()) continue;
                int front = s.pop();
    
                while(s.isEmpty()!= true){
                    int k = s.pop();
                    ans += Math.abs(k-front)-1;
                    front = k;
                }
            }
    
            System.out.println(ans);
    
    
    
    
        }
    }

     

     

     

    https://ethereal-coder.tistory.com/49

     

    백준 [자바 java] 1461 : 도서관

    https://www.acmicpc.net/problem/1461 1461번: 도서관 세준이는 도서관에서 일한다. 도서관의 개방시간이 끝나서 세준이는 사람들이 마구 놓은 책을 다시 가져다 놓아야 한다. 세준이는 현재 0에 있고, 사람

    ethereal-coder.tistory.com

    https://www.acmicpc.net/problem/1461

     

    1461번: 도서관

    세준이는 도서관에서 일한다. 도서관의 개방시간이 끝나서 세준이는 사람들이 마구 놓은 책을 다시 가져다 놓아야 한다. 세준이는 현재 0에 있고, 사람들이 마구 놓은 책도 전부 0에 있다. 각 책

    www.acmicpc.net

    사실 한번에 통과하긴 했지만 4번은 갈아엎었던 것 같다.

    처음에는 그냥 음수, 양수 나누어서 가장 끝에서부터 차례로 한번에 들을 수 있는 책 만큼 건너뛰면서 세면 되지 않을까라고 생각했지만 다시 0으로 돌아오지 않아도 된다는 조건 때문에 실패했다.

    그리고 받는 수를 다 우선순위큐에 넣어서 차례로 빼려고 했지만 그렇게 하면 양수부분에서는 절댓값이 작은 부분부터 탐색해서 옳은 답이 나오지 않는다. 

    최종적으로 지금 한 대로 양수는 양수대로 음수는 음수대로 절댓값이 큰 순서대로 탐색하고 두 값들을 우선순위큐(내림)으로 처리했지만, 모든 수가 양수, 음수인 경우는 고려하지 않아 테케에 통과하지 못했었다.

     

    앞으로 주의할 점 : 두 과정으로 나누는 방식을 사용했을 때 하나의 과정만 사용해야 하는 경우 꼭 고려하기

     

    풀이코드

    import java.util.*;
    import java.io.*;
    import java.math.*;
    
    
    public class Main {
    
    
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(br.readLine());
    
            int n = Integer.parseInt(st.nextToken());
            int m = Integer.parseInt(st.nextToken());
    
            st = new StringTokenizer(br.readLine());
    
    
            PriorityQueue<Integer> q2 = new PriorityQueue<>(Collections.reverseOrder());
    
            int[] arr = new int[n];
    
            for(int i =0;i<n;i++) {
                int k = Integer.parseInt(st.nextToken());
                arr[i] = k;
            }
    
            Arrays.sort(arr);
    
            int ans = 0;
    
            int now = 0;
    
            while(true){
                if(arr[0] > 0) break;
                //System.out.println(arr[now]);
                q2.offer(Math.abs(arr[now]));
                now += m;
                if(now >= n || arr[now] >= 0) break;
            }
    
            now = n-1;
    
    
    
            while(true){
                if(arr[n-1] < 0) break;
                //System.out.println(arr[now]);
                q2.offer(Math.abs(arr[now]));
                now -= m;
                if(now < 0 || arr[now] < 0) break;
            }
    
            if(q2.isEmpty() != true) ans += q2.poll();
    
            while(q2.isEmpty() != true){
                ans += (q2.poll())*2;
            }
    
            System.out.println(ans);
    
        }
    }

     

    느낀점 

    앞으로 알고리즘을 더 빠르게, 효율적으로 풀기 위해 알고리즘 개념을 많이 알아야 할 것 같고 감을 잃지 않게 꾸준하게 풀어야겠다.