[Java, JS]_14719_빗물

hanseungjune·2023년 7월 4일
0

알고리즘

목록 보기
21/33
post-thumbnail

작성 코드

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

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

        int h = Integer.parseInt(st.nextToken());
        int w = Integer.parseInt(st.nextToken());

        List<Integer> blocks = new ArrayList<>();
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < w; i++){
            blocks.add(Integer.parseInt(st.nextToken()));
        }

        int result = calculater_rainwater(h, w, blocks);
        System.out.println(result);
    }

    public static int calculater_rainwater (int h, int w, List<Integer> blocks) {
        int total = 0;
        for (int i = 1; i < w-1; i++){
            int left_max = Collections.max(blocks.subList(0, i));
            int right_max = Collections.max(blocks.subList(i+1, blocks.size()));

            if (blocks.get(i) < left_max && blocks.get(i) < right_max) {
                total += Math.min(left_max, right_max) - blocks.get(i);
            }
        }
        return total;
    }
}

설명

코드의 로직을 리스트 형태로 설명하면 다음과 같습니다:

  • BufferedReader를 사용하여 입력을 받습니다.
  • StringTokenizer를 사용하여 첫 번째 줄에서 세로 길이 h와 가로 길이 w를 읽어옵니다.
  • 빈 리스트 blocks를 생성합니다.
  • StringTokenizer를 사용하여 두 번째 줄에서 공백을 기준으로 블록의 높이를 읽어와 blocks 리스트에 추가합니다.
  • 빗물의 총량을 저장할 total 변수를 0으로 초기화합니다.
  • w-1까지 반복하는 i의 범위로 루프를 실행합니다.
  • 현재 열 i에서 왼쪽의 최대 높이인 left_max를 구합니다. 이를 위해 blocks 리스트의 0부터 i-1까지의 부분 리스트에서 최댓값을 찾습니다.
  • 현재 열 i에서 오른쪽의 최대 높이인 right_max를 구합니다. 이를 위해 blocks 리스트의 i+1부터 끝까지의 부분 리스트에서 최댓값을 찾습니다.
  • 만약 현재 열의 높이인 blocks[i]가 왼쪽 최대 높이인 left_max보다 작고, 오른쪽 최대 높이인 right_max보다 작다면 빗물이 고이게 됩니다.
  • 빗물이 고이는 양은 Math.min(left_max, right_max) - blocks[i]로 계산됩니다. 이 값을 total에 더합니다.
  • 모든 반복이 완료되면 total 변수에 빗물의 총량이 저장되고, 이 값을 반환합니다.
  • 최종 결과를 출력합니다.

자바스크립트

const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

function calculateRainwater(h, w, blocks) {
  let total = 0;
  for (let i = 1; i < w - 1; i++) {
    const leftMax = Math.max(...blocks.slice(0, i));
    const rightMax = Math.max(...blocks.slice(i + 1));

    if (blocks[i] < leftMax && blocks[i] < rightMax) {
      total += Math.min(leftMax, rightMax) - blocks[i];
    }
  }
  return total;
}

rl.on("line", (line) => {
  const input = line.split(" ");
  const h = parseInt(input[0]);
  const w = parseInt(input[1]);

  rl.on("line", (line) => {
    const blocks = line.split(" ").map(Number);
    const result = calculateRainwater(h, w, blocks);
    console.log(result);
    rl.close();
  });
});

파이썬

h, w = map(int, input().split())
blocks = list(map(int, input().split()))

def calculate_rainwater(h, w, blocks):
    total = 0
    for col in range(1, w-1):
        left_max = max(blocks[:col])
        right_max = max(blocks[col+1:])
        
        if blocks[col] < left_max and blocks[col] < right_max:
            total += min(left_max, right_max) - blocks[col]
            
    return total

result = calculate_rainwater(h, w, blocks)
print(result)
profile
필요하다면 공부하는 개발자, 한승준

0개의 댓글