티스토리 뷰

컴퓨터공학/Problem Solving

백준 1327

_Bibidi 2021. 1. 15. 16:37
 

1327번: 소트 게임

첫째 줄에 순열의 크기 N과 K가 주어진다. N은 2보다 크거나 같고, 8보다 작거나 같다. 둘째 줄에 순열에 들어가는 수가 주어진다.

www.acmicpc.net

 

bit 최적화 연습용 문제

1. int형 숫자를 3bit씩 나눠서 각 3비트가 하나의 숫자를 나타내도록 함. 100은 1, 010은 2, 001은 4를 나타냄. 원래 표기법과 반대지만 구현은 이쪽이 더 편함.

2. BFS를 이용해서 풀었고 중복 체크는 set을 이용했음.

 

구현

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF = 2e9;

int n, k;

void setDigit(int &bit, int k, int num) {
    for (int i = 0; i < 3; i++) {
        bit &= ~(1 << (3 * k + i));
        if (num & (1 << i))
            bit |= (1 << (3 * k + i));
    }
}

int getDigit(int &bit, int k) {
    int sum = 0;
    for (int i = 0; i < 3; i++) {
        if (bit & (1 << (3 * k + i)))
            sum += (1 << i);
    }
    return sum;
}

void swapDigit(int &bit, int pos1, int pos2) {
    int a = getDigit(bit, pos1);
    int b = getDigit(bit, pos2);
    setDigit(bit, pos2, a);
    setDigit(bit, pos1, b);
}

void swapDigitRange(int &bit, int s, int e) {
    while (s < e) {
        swapDigit(bit, s, e);
        s++; e--;
    }
}

void print(int bit) {
    for (int i = 0; i < n; i++) {
        int sum = 0;
        for (int j = 0; j < 3; j++) {
            if (bit & (1 << (3 * i + j)))
                sum += (1 << j);
        }
        cout << sum << ' ';
    }
    cout << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> n >> k;
    int start = 0;
    for (int i = 0; i < n; i++) {
        int t; cin >> t;
        setDigit(start, i, t - 1);
    }
    
    int target = 0;
    for (int i = 0; i < n; i++) {
        setDigit(target, i, i);
    }
    
    int ans = INF;
    set<int> du;
    du.insert(start);
    queue<pair<int, int>> q;
    q.push({start, 0});
    while (!q.empty()) {
        int cur = q.front().first;
        int dist = q.front().second;
        q.pop();
        
        if (cur == target) {
            ans = dist;
            break;
        }
        
        for (int i = 0; i < n - k + 1; i++) {
            swapDigitRange(cur, i, i + k - 1);
            if (!du.count(cur)) {
                du.insert(cur);
                q.push({cur, dist + 1});
            }
            swapDigitRange(cur, i, i + k - 1);
        }
    }
    if (ans == INF) cout << -1;
    else cout << ans;
    return 0;
}

 

'컴퓨터공학 > Problem Solving' 카테고리의 다른 글

백준 11997  (0) 2021.01.17
백준 1194  (0) 2021.01.16
백준 1405  (0) 2021.01.15
백준 10265  (0) 2021.01.12
백준 2840  (0) 2021.01.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함