[Java, JS, Python]_2251_물통

hanseungjune·2023년 7월 15일
0

알고리즘

목록 보기
28/33
post-thumbnail

자바

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

public class water_bottle_2251 {
    static boolean[][][] visited = new boolean[201][201][201];
    static ArrayList<Integer> result = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
        int C = Integer.parseInt(st.nextToken());

        bfs(A, B, C);
        Collections.sort(result);

        for (int ans : result) {
            System.out.print(ans + " ");
        }
    }

    public static void bfs(int a, int b, int c) {
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0, c});

        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            int x = cur[0], y = cur[1], z = cur[2];

            if (!visited[x][y][z]) {
                visited[x][y][z] = true;
                if (x == 0) {
                    result.add(z);
                }

                // x -> y
                if (x + y > b) {
                    queue.offer(new int[]{x + y - b, b, z});
                } else {
                    queue.offer(new int[]{0, x + y, z});
                }

                // x -> z
                if (x + z > c) {
                    queue.offer(new int[]{x + z - c, y, c});
                } else {
                    queue.offer(new int[]{0, y, x + z});
                }

                // y -> x
                if (x + y > a) {
                    queue.offer(new int[]{a, x + y - a, z});
                } else {
                    queue.offer(new int[]{x + y, 0, z});
                }

                // y -> z
                if (y + z > c) {
                    queue.offer(new int[]{x, y + z - c, c});
                } else {
                    queue.offer(new int[]{x, 0, y + z});
                }

                // z -> x
                if (x + z > a) {
                    queue.offer(new int[]{a, y, x + z - a});
                } else {
                    queue.offer(new int[]{x + z, y, 0});
                }

                // z -> y
                if (y + z > b) {
                    queue.offer(new int[]{x, b, y + z - b});
                } else {
                    queue.offer(new int[]{x, y + z, 0});
                }
            }
        }
    }
}

로직 설명

이 코드는 세 개의 물통 A, B, C가 있고, 각각의 물통은 서로 물을 부을 수 있을 때, A 물통이 비어 있을 때, C 물통에 담길 수 있는 물의 양을 구하는 문제를 해결합니다.

처음에는 모든 물통이 빈 상태로 시작하지만, C 물통은 가득 차 있습니다. 따라서 BFS를 시작할 때 물통 C에 있는 물의 양은 최대 값이며, 물통 A와 B는 비어 있습니다.

그런 다음, 모든 가능한 상태에 대해 물을 부을 수 있는지 확인합니다. 한 물통에서 다른 물통으로 물을 부을 때, 목표 물통이 가득 찰 때까지 물을 부르거나, 원래 물통이 비어질 때까지 물을 부릅니다. 이 작업은 각 물통이 목표가 될 때까지, 즉 x -> y, x -> z, y -> x, y -> z, z -> x, z -> y에 대해 수행됩니다.

이 프로세스를 통해, 새로운 상태(즉, 각 물통에 있는 물의 양)를 큐에 추가합니다. 그러나 그 상태를 이미 방문했다면(즉, 그 상태가 이미 큐에 있었다면), 그 상태를 무시합니다. 이렇게 하여 중복된 상태를 피하며, BFS를 통해 가능한 모든 상태를 검사합니다.

마지막으로, 물통 A가 비어 있는 모든 경우에 대해 물통 C에 얼마나 많은 물이 담겼는지 확인하고, 그 결과를 정렬한 다음 출력합니다. 이렇게 함으로써, 물통 A가 비어 있을 때 물통 C에 담길 수 있는 모든 물의 양을 찾을 수 있습니다.

노드

const fs = require("fs");
const input = fs
  .readFileSync("/dev/stdin")
  .toString()
  .trim()
  .split(" ")
  .map(Number);
let visited = Array.from({ length: 201 }, () =>
  Array.from({ length: 201 }, () => Array(201).fill(false))
);
let result = [];

let [A, B, C] = input;

let queue = [];
queue.push([0, 0, C]);

while (queue.length !== 0) {
  let [x, y, z] = queue.shift();

  if (!visited[x][y][z]) {
    visited[x][y][z] = true;
    if (x === 0) {
      result.push(z);
    }

    // x -> y
    if (x + y > B) {
      queue.push([x + y - B, B, z]);
    } else {
      queue.push([0, x + y, z]);
    }

    // x -> z
    if (x + z > C) {
      queue.push([x + z - C, y, C]);
    } else {
      queue.push([0, y, x + z]);
    }

    // y -> x
    if (x + y > A) {
      queue.push([A, x + y - A, z]);
    } else {
      queue.push([x + y, 0, z]);
    }

    // y -> z
    if (y + z > C) {
      queue.push([x, y + z - C, C]);
    } else {
      queue.push([x, 0, y + z]);
    }

    // z -> x
    if (x + z > A) {
      queue.push([A, y, x + z - A]);
    } else {
      queue.push([x + z, y, 0]);
    }

    // z -> y
    if (y + z > B) {
      queue.push([x, B, y + z - B]);
    } else {
      queue.push([x, y + z, 0]);
    }
  }
}

result.sort((a, b) => a - b);

console.log(result.join(" "));

파이썬

from collections import deque

A, B, C = map(int, input().split())
visited = [[[False] * 201 for _ in range(201)] for _ in range(201)]
result = []

def bfs(a, b, c):
    queue = deque()
    queue.append((0, 0, c))
    
    while queue:
        x, y, z = queue.popleft()
        
        if not visited[x][y][z]:
            visited[x][y][z] = True
            if x == 0:
                result.append(z)
                
            # x -> y
            if x + y > b:
                queue.append((x + y - b, b, z))
            else:
                queue.append((0, x + y, z))
                
            # x -> z
            if x + z > c:
                queue.append((x + z - c, y, c))
            else:
                queue.append((0, y, x + z))
                
            # y -> x
            if x + y > a:
                queue.append((a, x + y - a, z))
            else:
                queue.append((x + y, 0, z))

            # y -> z
            if y + z > c:
                queue.append((x, y + z - c, c))
            else:
                queue.append((x, 0, y + z))
            
            # z -> x
            if x + z > a:
                queue.append((a, y, x + z - a))
            else:
                queue.append((x + z, y, 0))
                            
            # z -> y      
            if y + z > b:
                queue.append((x, b, y + z - b))
            else:
                queue.append((x, y + z, 0))          
    
bfs(A, B, C)
result.sort()

for ans in result:
    print(ans, end=' ')
profile
필요하다면 공부하는 개발자, 한승준

0개의 댓글

Powered by GraphCDN, the GraphQL CDN