CS/알고리즘_문제풀이(자바)

퍼즐

Jedy_Kim 2021. 11. 17. 16:57
728x90

https://www.acmicpc.net/problem/1525

 

1525번: 퍼즐

세 줄에 걸쳐서 표에 채워져 있는 아홉 개의 수가 주어진다. 한 줄에 세 개의 수가 주어지며, 빈 칸은 0으로 나타낸다.

www.acmicpc.net

 

// 코드

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
import java.util.*;
import java.io.*
 
 
public class Main { 
  
  
  // main
  public static void main(String[] args) throws Exception{
    
    // Please Enter Your Code Here
    BufferedWriter bw  = new BufferedWriter(new OutputStreamWriter(System.out));
    BufferedReader br  = new BufferedReader(new InputStreamReader(System.in)); 
    StringTokenizer st = null;
    
    // 입력값을 배열이 아닌 하나의 값으로 처리한다.
    int start = 0;
    for(int i=0; i<3++i) {
      st = new StringTokenizer(br.readLine());
      for(int j=0; j<3++j) {
        int num = Integer.parseInt(st.nextToken());
        if(num == 0) num = 9;
        start = (start * 10+ num;
      }
    }
    
    Deque<Integer> deq        = new ArrayDeque<>();
    Map<Integer, Integer> map = new HashMap<>();
    int[][] DELTAS            = { {-10}, {10}, {0-1}, {01} };
    
    deq.offer(start);
    map.put(start, 0);
    
    while(!deq.isEmpty()) {
      
      int num = deq.poll();
      // 9의 인덱스 위치를 찾는다.
      String now  = String.valueOf(num);
      int nineIdx = now.indexOf('9');
      
      int nineRowIdx = nineIdx / 3;
      int nineColIdx = nineIdx % 3;
      
      for(int i=0; i<4++i) {
        int ny = nineRowIdx + DELTAS[i][0];
        int nx = nineColIdx + DELTAS[i][1];
        
        if(ny < 0 || ny >= 3 || nx < 0 || nx >= 3continue;
        
        int move = (ny * 3+ nx;
        // ny, nx 값을 평면의 위치로..
        StringBuilder sb = new StringBuilder(now);  
        
        char temp = now.charAt(move);
        sb.setCharAt(move, '9');
        sb.setCharAt(nineIdx, temp);
        
        int next = Integer.parseInt(sb.toString());
        if(map.containsKey(next)) continue;
        
        deq.offer(next);
        map.put(next, map.get(num) + 1); 
      } 
    }
    
    int res = map.containsKey(123456789) ? map.get(123456789) : -1;
    bw.write(String.valueOf(res));
    
    bw.flush();
    bw.close();
    br.close();
  }
   
cs

 

// 복습

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
import java.util.*;
import java.io.*
 
public class Main {    
  
  static final int[][] DELTAS       = { { -10 }, { 10 }, { 0-1 }, { 01 } };
  static final int FINDVAL          = 123456789;
  static int givenVal               = 0;
  static Map <Integer, Integer> map = new HashMap <> ();
  
  
  // main
  public static void main (String[] args) throws Exception{
    
    // Please Enter Your Code Here 
    BufferedWriter bw  = new BufferedWriter ( new OutputStreamWriter ( System.out ) );
    BufferedReader br  = new BufferedReader ( new InputStreamReader  ( System.in ) );
    StringTokenizer st = null;
    
    // 초기화
    for ( int i = 0; i < 3++i ) {
      st = new StringTokenizer ( br.readLine () );
      for ( int j = 0; j < 3++j ) {
        
        int num = Integer.parseInt ( st.nextToken () );
        num = ( num == 0 ) ? 9 : num;
        givenVal = ( givenVal * 10 ) + num;
        
      }
    }
    
    // 탐색 시작
    bfs ();
    // 정답 찾기
    int ret = ( map.containsKey ( FINDVAL ) ? map.get ( FINDVAL ) : -1 );
    // 정답 출력
    bw.write( String.valueOf ( ret ) );
    
    // 종료
    bw.flush ();
    bw.close ();
    br.close ();
    
  }   
  
  
  // 모든 경우를 탐색하는 메서드
  static void bfs () {
    
    Deque <Integer> deq = new ArrayDeque <> ();
    deq.offer ( givenVal );
    map.put ( givenVal, 0 );
    
    // 탐색 시작
    while ( !deq.isEmpty () ) {
      
      int pollNum = deq.poll ();
      
      // 9의 위치를 찾아낸다.
      String strNum = String.valueOf ( pollNum );
      int nineIdx   = strNum.indexOf ( '9' );
      
      // 9의 위치를 2차원에서의 행, 열의 인덱스를 구한다
      int nineRowIdx = nineIdx / 3;
      int nineColIdx = nineIdx % 3;
      
      // 4방 탐색
      for ( int dir = 0; dir < 4++dir ) {
        
        int ny = nineRowIdx + DELTAS[ dir ][ 0 ];
        int nx = nineColIdx + DELTAS[ dir ][ 1 ];
        if ( ny < 0 || ny >= 3 || nx < 0 || nx >= 3 ) continue;
        
        // 2차원에서의 행, 열의 값을 다시 평면에서의 인덱스 값으로 치환해준다.
        int next = ( ny * 3 ) + nx;
        
        // 9의 위치를 주변의 값들과 바꿔준다.
        StringBuilder sb = new StringBuilder (strNum);
        char temp = strNum.charAt (next);
        sb.setCharAt ( next, '9' );
        sb.setCharAt ( nineIdx, temp );
        
        // 바꿔준 값을 map에 key로 이미 가지고 있는지 체크해준다.
        int nextNum = Integer.parseInt( sb.toString() );
        // 이미 있는 경우 필터링
        if ( map.containsKey ( nextNum ) ) continue;
        // 없는 경우 : 기존의 값을 가져와서 + 1 해준다.
        map.put ( nextNum, ( map.get ( pollNum ) + 1 ) ); 
        // 다시 큐에 넣어준다.
        deq.offer ( nextNum );
        
      }
      
    } // 탐색 끝
    
  } // 모든 경우를 탐색하는 메서드 종료
  
cs

 

반응형

'CS > 알고리즘_문제풀이(자바)' 카테고리의 다른 글

팰린드롬?  (0) 2021.11.18
물통  (0) 2021.11.18
부등호  (0) 2021.11.08
수 이어 쓰기 1  (0) 2021.11.08
점프  (0) 2021.11.03