Skip to content

Conversation

@LiiNi-coder
Copy link
Contributor

🧷 문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/250136

🧭 풀이 시간

70 분

👀 체감 난이도

✏️ 문제 설명

  • 석유가 묻혀있는 곳은 1로 표기되고 아닌곳은 0으로 표기된 2차원 배열에서, 각 열마다 순회하여 해당 열의 모든 행의 석유를 탐사한다. 석유가 있는 칸을 발견하면, 그 칸의 인접한 모든 석유를 캐게된다. 그때 가장 많은 석유를 캐도록 할때의 값을 출력

🔍 풀이 방법

  • BFS

⏳ 회고

  • 처음엔 Point와 ID리스트를 만들어 객체 지옥을 만들어놓았다. 그래서 효율성 체크에서 현저히 떨어져, Point를 그냥 2차원배열로 나타내고, Id리스트도 그냥 정적 배열로 만들었더니 시간이 훨씬 줄었다. 웬만하면 Point를 쓰지말자.
// 이전코드
import java.util.*;
class Solution {
    static class Point{
        int r;
        int c;
        Point(int r, int c){
            this.r = r;
            this.c = c;
        }
        @Override
        public boolean equals(Object o){
            if(o == null || getClass() != o.getClass())
                return false;
            Point p = (Point)o;
            return (this.r == p.r) && (this.c == p.c);
        }
        @Override
        public int hashCode(){
            return Objects.hash(this.r, this.c);
        }
        @Override
        public String toString(){
            return "r:" + this.r + " c:" + this.c;
        }
        int atPoint(int[][] matrix){
            if(this.r < 0 || this.r>= matrix.length || this.c<0 || this.c >= matrix[0].length)
                return -1;
            return matrix[this.r][this.c];
        }
        Point transform(Point dp){
            return new Point(this.r + dp.r, this.c + dp.c);
        }
        void visit(){
            visited[this.r][this.c] = true;
        }
        boolean isVisit(){
            return visited[this.r][this.c];
        }
    }
    private static int R, C;
    private static HashMap<Point, Integer> IdAtPoint;
    private static List<Point> dPoints;
    private static boolean[][] visited;
    private static int[][] land;
    private static int count;
    private static List<Integer> countAtId;
    public int solution(int[][] lland) {
        land = lland;
        int answer = 0;
        R = land.length;
        C = land[0].length;
        visited = new boolean[R][C];
        dPoints = new LinkedList<Point>();
        dPoints.add(new Point(0, 1));
        dPoints.add(new Point(0, -1));
        dPoints.add(new Point(1, 0));
        dPoints.add(new Point(-1, 0));
        IdAtPoint = new HashMap<Point, Integer>();
        countAtId = new ArrayList<Integer>();
        // for c in 열
        for(int c = 0; c<C; c++){
            int oilAtCol = 0;
            var passedId = new HashSet<Integer>();
            for(int r= 0; r<R; r++){
                Point p = new Point(r, c);
                if(p.atPoint(land) == 0) continue;
                if(!IdAtPoint.containsKey(p)){
                    bfs(p, count++);
                    //print(IdAtPoint);
                }
                int IdAtP = IdAtPoint.get(p);
                if(passedId.contains(IdAtP))
                    continue;
                passedId.add(IdAtP);
                oilAtCol += countAtId.get(IdAtP);
                for(int cc: countAtId){
                    //System.out.print(cc + " ");
                    
                }
                //System.out.println();
            }
            answer = Math.max(answer, oilAtCol);
        }
        //# for r in 행
        //## 만약 r,c가 1이라면
        //### pointsAtOil에 r, c가 없다면
        //#### bfs해서 pointsAtOil기록
        //### pointsAtOil을 토대로 알아내기
        return answer;
    }
    
    private void bfs(Point startp, int id){
        var q = new ArrayDeque<Point>();
        int temp = 0;
        q.add(startp);
        startp.visit();
        IdAtPoint.put(startp, id);
        while(!q.isEmpty()){
            Point p = q.poll();
            temp++;
            for(Point dPoint : dPoints){
                
                Point np = p.transform(dPoint);
                if(!BC(np)) continue;
                if(np.isVisit()) continue;
                if(np.atPoint(land) == 0)continue;
                np.visit();
                q.add(np);
                IdAtPoint.put(np, id);
            }
        }
        countAtId.add(temp);
    }
    private boolean BC(Point p){
        return p.r>=0 && p.r<R && p.c>=0 && p.c<C;
    }
    private void print(int[][] matrix){
        for(int[] m: matrix){
            System.out.println(Arrays.toString(m));
            System.out.println();
        }
    }
    private void print(HashMap<Point, Integer> m){
        for(Map.Entry<Point, Integer> e: m.entrySet()){
            System.out.print(e.getKey() + " " + e.getValue() + "/ ");
        }
        System.out.println();
    }
}

@LiiNi-coder LiiNi-coder added hint 💡 반례를 참고했거나 힌트를 얻고 풀었을 때 timeout ⌚ 목표 시간보다 오래걸렸을 때 labels Aug 24, 2025
@ShinHeeEul ShinHeeEul merged commit 4831ed5 into main Aug 24, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hint 💡 반례를 참고했거나 힌트를 얻고 풀었을 때 timeout ⌚ 목표 시간보다 오래걸렸을 때

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants