[백준/7569] 토마토 (골드 5) JAVA

jkky98·2024년 6월 21일
0

CodingTraining

목록 보기
40/62
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

        String xyzinput = br.readLine();
        StringTokenizer st = new StringTokenizer(xyzinput, " ");
        int x = Integer.parseInt(st.nextToken());
        int y = Integer.parseInt(st.nextToken());
        int z = Integer.parseInt(st.nextToken());

        List<tomatoPlate> tomatoPlates = new ArrayList<>();
        for (int i = 0; i < z; i++) {
            tomatoPlate tomatoPlate = new tomatoPlate(x, y);
            for (int j = 0; j < y; j++) {
                String tomatoString = br.readLine();
                StringTokenizer stLine = new StringTokenizer(tomatoString, " ");
                List<Integer> tmp = new ArrayList<>();
                while (stLine.hasMoreTokens()) {
                    tmp.add(Integer.parseInt(stLine.nextToken()));
                }
                tomatoPlate.placeOf(tmp);
            }
            tomatoPlates.add(tomatoPlate);
        }

        // 타워 생성
        tomatoTower tomatoTower = new tomatoTower();
        // 토마토 층 넣기
        tomatoTower.setTower(tomatoPlates);
        ripeTomato ripeTomato = new ripeTomato(Main.tomatoTower.getTower(), x, y, z);
        ripeTomato.setProcess();
        ripeTomato.runProcess();


        if (ripeTomato.checkAll()) {
            System.out.println((ripeTomato.getDay() - 1));
        } else {
            System.out.println(-1);
        }

    }

    static class ripeTomato {
        private List<List<List<Integer>>> tower;
        private int x;
        private int y;
        private int z;
        private Deque<List<Integer>> deque = new ArrayDeque<>();
        private int day;

        public int getDay() {
            return day;
        }

        public ripeTomato(List<List<List<Integer>>> tower, int x, int y, int z) {
            this.tower = tower;
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public void setProcess() {
            for (int i=0; i < z; i++) {
                for (int j=0; j < y; j++) {
                    for (int k=0; k < x; k++) {
                        if (tower.get(i).get(j).get(k).equals(1)) {
                            deque.add(List.of(i,j,k));
                        }
                    }
                }
            }
        }

        public boolean checkAll() {
            for (int i=0; i < z; i++) {
                for (int j=0; j < y; j++) {
                    for (int k=0; k < x; k++) {
                        if (tower.get(i).get(j).contains(0)) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        public void runProcess() {
            ArrayDeque<List<Integer>> memory = new ArrayDeque<>();
            do {
                memory.clear();
                while(!deque.isEmpty()) {
                    List<Integer> tomato = deque.poll();
                    Deque<List<Integer>> riping = riping(tomato.get(0), tomato.get(1), tomato.get(2));
                    memory.addAll(riping);
                }
                deque.addAll(memory);
                day++;
            } while (!memory.isEmpty());
        }

        private Deque<List<Integer>> riping(Integer Z, Integer Y, Integer X) {
            ArrayDeque<List<Integer>> dequeTmp = new ArrayDeque<>();
            int z = Z;
            int x = X;
            int y = Y;
            tower.get(z).get(y).set(x, 9);

            if (z + 1 <= this.z-1) {
                if (tower.get(z+1).get(y).get(x) == 0)
                {
                    tower.get(z+1).get(y).set(x, 1);
                    dequeTmp.add(List.of(z+1,y,x));
                }
            }
            if (z - 1 >= 0) {
                if (tower.get(z-1).get(y).get(x) == 0)
                {
                    tower.get(z-1).get(y).set(x, 1);
                    dequeTmp.add(List.of(z-1,y,x));
                }
            }
            if (y + 1 <= this.y-1) {
                if (tower.get(z).get(y+1).get(x) == 0)
                {
                    tower.get(z).get(y+1).set(x, 1);
                    dequeTmp.add(List.of(z,y+1,x));
                }
            }
            if (y - 1 >= 0) {
                if (tower.get(z).get(y-1).get(x) == 0)
                {
                    tower.get(z).get(y-1).set(x, 1);
                    dequeTmp.add(List.of(z,y-1,x));
                }
            }
            if (x + 1 <= this.x-1) {
                if (tower.get(z).get(y).get(x+1) == 0)
                {
                    tower.get(z).get(y).set(x+1, 1);
                    dequeTmp.add(List.of(z,y,x+1));
                }
            }
            if (x - 1 >= 0) {
                if (tower.get(z).get(y).get(x-1) == 0)
                {
                    tower.get(z).get(y).set(x-1, 1);
                    dequeTmp.add(List.of(z,y,x-1));
                }
            }
            return dequeTmp;
        }
    }

    static class tomatoPlate {
        int x;
        int y;
        List<List<Integer>> plate = new ArrayList<>(new ArrayList<>());
        int count = 0;

        public tomatoPlate(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public void placeOf(List<Integer> inputList) {
            plate.add(inputList);
            count++;
        }

        public List<List<Integer>> getPlate() {
            return plate;
        }

    }

    static class tomatoTower {

        private static List<List<List<Integer>>> tower = new ArrayList<>();


        public void setTower(List<tomatoPlate> plates) {
            for (tomatoPlate plate : plates) {
                tower.add(plate.getPlate());
            }
        }

        public static List<List<List<Integer>>> getTower() {
            return tower;
        }
    }

}

객체지향식으로 풀려다가 3차원이어서 후회한 문제 Collection도 쓸 필요없이 그냥 [][][]로 묶어서 풀 걸 그랬다. 제네릭이랑 Collection 배운 김에 활용해서 풀어보았다. 아마 줄일 수 있는 구간들이 굉장히 많을 것 같다.

  1. tomatoplate를 만든다. List(List) - 2차원
  2. tomatoplate를 다시 리스트에 넣어 3차원 tomatoTower를 만든다.
  3. setProcess로 deque에 전체 조회를 진행하여 1에 해당하는 토마토 좌표 x,y,z를 얻는다.
  4. runProcess로 하여금 번져나가도록 한다. riping 메서드가 BFS에 해당한다.

특이사항. doWhile문을 통해 처음에 memory가 비었을 때도 그냥 돌게끔 설계했다. 2차원 그래프문제를 BFS, DFS로 파이썬으로 풀어도 꽤 길었는데 자바로 객체지향적으로 푸니 더 길어보인다. 숏코딩 실패.

소요시간 : 2시간

profile
자바집사의 거북이 수련법

0개의 댓글

관련 채용 정보