개발/알고리즘

골드 2 백준 (8-puzzle) 1525

차가운콩 2025. 6. 24. 22:59
#include <iostream>
#include <queue>
#include <set>

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int twoPointToOnePoint(std::pair<int, int> tp) {
    return tp.first * 3 + tp.second;
}

std::pair<int, int> onePointToOnePoint(int op) {
    return {op / 3, op % 3};
}

int calculate(std::string strValue) {
    std::string answer = "123456780";

    if (answer == strValue) {
        return 0;
    }

    std::queue<std::pair<std::string, short> > q;

    std::set<std::string> visited;

    visited.insert(strValue);
    q.push(make_pair(strValue, 0));

    while (!q.empty()) {
        auto [current, index] = q.front();
        q.pop();

        if (current == answer) {
            return index;
        }

        int zeroPos = current.find("0");
        auto [posX, posY] = onePointToOnePoint(zeroPos);

        for (int i = 0; i < 4; i++) {
            int nx = posX + dx[i];
            int ny = posY + dy[i];

            if (nx < 0 || ny < 0 || nx >= 3 || ny >= 3) continue;

            std::string temp = current;
            int onePoint = twoPointToOnePoint({nx, ny});
            std::swap(temp[zeroPos], temp[onePoint]);

            if (visited.find(temp) != visited.end()) continue;

            q.push(make_pair(temp, index + 1));
            visited.insert(temp);
        }
    }

    return -1;
}

int main() {
    std::string strValue, inpuStr;
    strValue = "";

    for (int i = 0; i < 9; i++) {
        std::cin >> inpuStr;

        strValue += inpuStr;
    }

    std::cout << calculate(strValue);
}