아무코딩

[백준 2931] 가스관(java) 본문

알고리즘/백준

[백준 2931] 가스관(java)

동 코 2020. 5. 20. 16:17

문제풀이

매우 복잡하게 푼거 같은느낌이 든 문제이다.

 

1. 탐색은 bfs를 사용하였고 bfs를 사용하여 계속 파이프를 따라간다.

2. 파이프가 이어져야 하는 곳에 파이프가 없을때('.' 일때)

3. 해당 위치에서 사방을 탐색하여 적절한 파이프를 기존에 저장해놓았던 map에서 반환한다. 

 

모든 걸 넣어보고 문제없는지 확인하는 방법도 있겠지만 더 효율적으로 짜보고자 map을 활용하였다.

 

소스코드

더보기
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
 
public class Baekjoon2931 {
 
    static int rowSize;
    static int colSize;
    static char[][] map;
    static boolean[][] visited;
    static Position Src,Dest;
    static Map<Character, Object> pipe;
    static Map<String,Character> print;
    static int dirRow[] = {0,1,0,-1};
    static int dirCol[] = {1,0,-1,0};
    public static class Position{
        int row,col;
        public Position(int row, int col) {
            this.row = row;
            this.col = col;
        }
    }
 
    public static boolean isRange(int nextRow,int nextCol){
        if(nextRow<0||nextRow>=rowSize || nextCol<0 || nextCol>=colSize)
            return false;
        return true;
    }
    public static boolean isPipe(int nextRow,int nextCol){
        if(map[nextRow][nextCol]=='.')
            return false;
        return true;
    }
    public static String bfs(){
        Queue<Position> q = new LinkedList<>();
        visited[Src.row][Src.col]=true;
        for(int i=0;i<4;i++){
            int nextRow = Src.row + dirRow[i];
            int nextCol = Src.col + dirCol[i];
            if(!isRange(nextRow,nextCol)||!isPipe(nextRow,nextCol))
                continue;
            q.add(new Position(nextRow,nextCol));
            visited[nextRow][nextCol] = true;
            break;//모스크바는 하나의 블록과만 인접함.
        }
 
        while(!q.isEmpty()){
            Position cur = q.poll();
            visited[cur.row][cur.col] = true;
            char curPipe = map[cur.row][cur.col];
            if(curPipe=='.'){//길이 끊어져 있는
                String temp ="";
                for(int i=0;i<4;i++){
                    int nextRow = cur.row + dirRow[i];
                    int nextCol = cur.col + dirCol[i];
                    if(!isRange(nextRow,nextCol)||!isPossible(nextRow,nextCol,i))
                        temp+="0";
                    else
                        temp+="1";
                }
                return (cur.row+1)+" "+(cur.col+1)+" "+print.get(temp);
            }
            boolean[] pipeInfo = (boolean[]) pipe.get(curPipe);
            for(int i=0;i<4;i++){
                int nextRow = cur.row + dirRow[i];
                int nextCol = cur.col + dirCol[i];
                if(!isRange(nextRow,nextCol)||visited[nextRow][nextCol]||!pipeInfo[i]) continue;
                q.add(new Position(nextRow,nextCol));
                visited[nextRow][nextCol] = true;
            }
        }
        return "";
    }
 
    public static boolean isPossible(int row, int col, int i) {
        switch (map[row][col]){
            case '|':
                if(i==1||i==3)
                    return true;
                return false;
            case '-':
                if(i==0||i==2)
                    return true;
                return false;
            case '+':
                return true;
            case '1':
                if(i==0||i==1)
                    return false;
                return true;
            case '2':
                if(i==0||i==3)
                    return false;
                return true;
            case '3':
                if(i==2||i==3)
                    return false;
                return true;
            case '4':
                if(i==1||i==2)
                    return false;
                return true;
            default:
                return false;
        }
    }
 
    public static void main(String[] args) throws IOException {
        initData();
        String result = bfs();
        System.out.println(result);
    }
 
    public static void initData() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        rowSize = Integer.parseInt(st.nextToken());
        colSize = Integer.parseInt(st.nextToken());
        map = new char[rowSize][colSize];
        visited = new boolean[rowSize][colSize];
        pipe = new HashMap<Character, Object>();
        print = new HashMap<String,Character>();
        pipe.put('|',new boolean[] {false,true,false,true});
        pipe.put('-',new boolean[] {true,false,true,false});
        pipe.put('+',new boolean[] {true,true,true,true});
        pipe.put('1',new boolean[] {true,true,false,false});
        pipe.put('2',new boolean[] {true,false,false,true});
        pipe.put('3',new boolean[] {false,false,true,true});
        pipe.put('4',new boolean[] {false,true,true,false});
        print.put("0101",'|');
        print.put("1010",'-');
        print.put("1111",'+');
        print.put("1100",'1');
        print.put("1001",'2');
        print.put("0011",'3');
        print.put("0110",'4');
 
        for(int i=0;i<rowSize;i++){
            String str = br.readLine();
            for(int j=0;j<colSize;j++){
                char ch = str.charAt(j);
                map[i][j] = ch;
                if(ch =='M')
                    Src = new Position(i,j);
                else if(ch == 'Z')
                    Dest = new Position(i,j);
            }
        }
    }
}
 
cs

문제 링크 : www.acmicpc.net/problem/2931

 

2931번: 가스관

문제 러시아 가스를 크로아티아로 운반하기 위해 자그레브와 모스코바는 파이프라인을 디자인하고 있다. 두 사람은 실제 디자인을 하기 전에 파이프 매니아 게임을 이용해서 설계를 해보려고 �

www.acmicpc.net

Comments