Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • Kubernetes
  • docker
  • BFS
  • 다이나믹 프로그래밍
  • django
  • 프로그래머스
  • Network
  • 백트래킹
  • boj
  • DFS

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[백준 1525] 퍼즐 (C++)
Algorithm/BOJ

[백준 1525] 퍼즐 (C++)

2021. 8. 30. 16:18
 

1525번: 퍼즐

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

www.acmicpc.net

BFS, 비트마스킹


3x3 크기의 퍼즐은 각 칸마다 0~8까지의 숫자가 들어간다는 것을 이용해서 

하나의 숫자당 4개의 비트를 사용.

long long 타입에서 총 36개의 비트를 사용해 3x3 퍼즐의 정보를 저장하도록 했다.

위 퍼즐에서 0의 위치는 3행 3열에 있다. 따라서 32번째 비트~35번째 비트 공간이 해당 칸을 저장하게된다.

그리고 특정 칸에 위치한 숫자를 알아내기 위한 mask로서 Checker배열을 설정했다.

 

BFS를 수행하면서 매번 0의 위치를 찾아준다.

0의 위치를 찾았다면 0이 갈 수 있는 4방향을 모두 탐색해본다.

범위를 벗어나지 않는다면 해당 방향에 있는 숫자와 0의 위치를 바꾼 후 next퍼즐 비트에 저장한다.

이때 같은 비트를 중복해서 탐색하지 않도록 set을 활용해서 visited 배열을 구성했다.

 

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
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <cstring>
#define fasti ios_base::sync_with_stdio(false); cin.tie(0);
#define fastio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define INF 1e9+7
 
typedef long long ll;
#define pli pair<ll, int>
 
using namespace std;
 
 
ll start, answer, offset = 15;
ll Checker[9];
set<ll> Check;
int dr[4] = {0, 0, 1, -1};
int dc[4] = {1, -1, 0, 0};
 
void input(){
    ll a;
    for(int i = 0; i < 9; i++){
        cin >> a;
        a = (a << i*4);
        start += a;
    }
    
    for(ll i = 1; i <= 9; i++){
        answer += (i % 9 << (i-1)*4);
    }
    
    for(int i = 0; i < 9; i++){
        Checker[i] = (offset << i*4);
    }
}
 
int find_zero_loc(ll puzzle){
    ll k;
    for(int i = 0; i < 9; i++){
        k = Checker[i]&puzzle;
        if(k >> i*4 == 0){
            return i;
        }
    }
    return -1;
}
 
// loc1(zero)과 loc2에 있는 숫자를 swap
ll set_puzzle(ll puzzle, int loc1, int loc2){
    ll num = (Checker[loc2]&puzzle) >> loc2*4;
    
    puzzle &= ~(offset << loc2*4);
    puzzle |= (num << loc1*4);
    
    return puzzle;
}
 
void solve(){
    queue<pli > que;
    que.push({start, 0});
    Check.insert(start);
    
    while(!que.empty()){
        pli now = que.front();
        que.pop();
        
        if(now.first == answer){
            cout << now.second << "\n";
            return;
        }
        
        int zero = find_zero_loc(now.first);
        int r = zero / 3;
        int c = zero % 3;
        
        for(int i = 0; i < 4; i++){
            int nr = r + dr[i];
            int nc = c + dc[i];
            if(nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue;
            
            ll next = set_puzzle(now.first, zero, nr*3 + nc);
            if(Check.count(next) > 0) continue;
            
            Check.insert(next);
            que.push({next, now.second+1});
        }
    }
    
    cout << -1 << "\n";
}
 
int main(){
    input();
    solve();
    
    return 0;
}
 
Colored by Color Scripter
cs

'Algorithm > BOJ' 카테고리의 다른 글

[백준 1339] 단어수학 (C++)  (0) 2021.09.12
[백준 2529] 부등호 (C++)  (0) 2021.09.12
[백준 17472] 다리 만들기 2 (C++)  (0) 2021.08.25
[백준 1395] 스위치 (C++)  (0) 2021.08.17
[백준 15559] 내 선물을 받아줘 (C++)  (0) 2021.08.13
    'Algorithm/BOJ' 카테고리의 다른 글
    • [백준 1339] 단어수학 (C++)
    • [백준 2529] 부등호 (C++)
    • [백준 17472] 다리 만들기 2 (C++)
    • [백준 1395] 스위치 (C++)

    티스토리툴바