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

 

 

 

 

 

#문제 간단 정리

브루트포스 완전탐색을 활용하자

bfs 를 활용하면 된다

 

 

#문제 해결 방법

 

일단 문제가 좀 설명이 길기 때문에 이해하기 좀 걸릴 수가 있다.

 

우선 이 문제에서 주목해야 될 포인트는 4가 넘어가면 5로 나눈 값으로 큐브값을 유지한다는것이다.

 

그렇다면 우리는 스위치의 개수도 8개로 가짓수가 적고

계속해서 5로 나눈다면 같은 상태가 반복된다는 걸 알 수 있다.

이부분에서 전체 가짓수가 적다는걸 파악한다

 

여기서 같은 스위치를 대략 최대 4번정도 누른다면 원래 상태로 되돌아 올 수 있다는 걸 관찰 할 수 있고

각 스위치 하나마다 최대 5가지의 상태가 파생되니까

5^k 가 총 가짓수인걸 파악할 수 있다.

 

그렇다면 중복상태를 뛰어넘어서 완전탐색을 하면 되겟다는 생각이 든다. (가짓수가 적으니까)

 

-> 여기서 중복 제거를 위해서 맵이나 셋으로 중복 상태를 관리하고

-> 완전탐색은 최소 거리를 찾아야되기 때문에 bfs 가 적절하다는 생각이 든다.

 

 

 

그렇다면 이제 구현할 차례,

유의할점은 애초에 주어진 상태가 전부 같은 숫자로 주어진 

정답 상태로 초기에 주어질 수 있음만 유의하도록 하자.

 

자세한 구현은 코드보고 이해하도록 하자

 

 

#전체 코드

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>

using namespace std;

// 모든 큐브의 숫자가 동일한지 확인하는 함수
bool equal(vector<int>& vec) {
    for (int i = 1; i < vec.size(); i++) {
        if (vec[i] != vec[0]) {
            return false;
        }
    }
    return true;
}

int main() {
    
    int n, k;
    cin >> n >> k;
    
    vector<int> cubes;
    for (int i = 0; i < n; i++) {
        int input;
        cin >> input;
        cubes.push_back(input);
    }
    
    vector<vector<int>> switches(k);
    for (int i = 0; i < k; i++) {
        int input;
        cin >> input;

        for (int j = 0; j < input; j++) {
            int input2; cin >> input2;
            switches[i].push_back(input2-1);
        }

    }

    set<vector<int>> cubeSet;


    //큐브상태,횟수
    queue<pair<vector<int>,int>> q;
    q.push({ cubes,0 });
    cubeSet.insert(cubes);

    while (!q.empty()) {

        vector<int> front = q.front().first;
        int seq = q.front().second;
        q.pop();
        if (equal(front)) {
            cout << seq  << '\n';
            return 0;
        }
         
        for (int i = 0; i < k; i++) {
            vector<int> next = front;
            for (auto a : switches[i]) {
                next[a] += i+1;
                if (next[a] > 4) {
                    next[a] %= 5;
                }
            }
            if (cubeSet.find(next) == cubeSet.end()) {
                cubeSet.insert(next);
                q.push({ next,seq + 1 });
            }

        }

    }

    cout << -1 << '\n';
    

    return 0;
}

 

 

//주석달린 버전

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>

using namespace std;

// 모든 큐브의 숫자가 동일한지 확인하는 함수
bool equal(vector<int>& vec) {
    for (int i = 1; i < vec.size(); i++) {
        if (vec[i] != vec[0]) {
            return false;
        }
    }
    return true;
}

int main() {
    int n, k;
    cin >> n >> k;
    
    vector<int> cubes(n);
    for (int i = 0; i < n; i++) {
        cin >> cubes[i];
    }
    
    vector<vector<int>> switches(k);
    for (int i = 0; i < k; i++) {
        int m;
        cin >> m;
        switches[i].resize(m);
        for (int j = 0; j < m; j++) {
            cin >> switches[i][j];
            switches[i][j]--; // 1-based index를 0-based index로 변환
        }
    }

    // 중복 상태 관리를 위한 set
    set<vector<int>> visited;

    // 큐브 상태와 스위치를 누른 횟수를 저장할 큐
    queue<pair<vector<int>, int>> q;
    q.push({cubes, 0});
    visited.insert(cubes);

    while (!q.empty()) {
        vector<int> current = q.front().first;
        int moves = q.front().second;
        q.pop();

        // 모든 큐브의 숫자가 동일하면 정답 출력 후 종료
        if (equal(current)) {
            cout << moves << endl;
            return 0;
        }

        // 각 스위치를 한번씩 눌러보는 과정
        for (int i = 0; i < k; i++) {
            vector<int> next = current;
            for (int idx : switches[i]) {
                next[idx] = (next[idx] + (i + 1)) % 5; // 스위치에 따라 숫자 변경
            }

            // 이미 방문한 상태가 아니면 큐와 set에 추가
            if (visited.find(next) == visited.end()) {
                visited.insert(next);
                q.push({next, moves + 1});
            }
        }
    }

    // 모든 경우를 탐색했음에도 정답을 찾지 못한 경우
    cout << -1 << endl;
    return 0;
}

'[백준] > C++' 카테고리의 다른 글

백준 19554번 Guess the number [C++]  (0) 2024.08.25
백준 17610번 양팔저울 [C++]  (0) 2024.08.25
백준 14760번 Reverse Nonogram [C++]  (0) 2024.08.23
백준 6123번 O Those Fads [C++]  (0) 2024.07.27
백준 1059번 좋은 구간 [C++]  (0) 2024.07.25

+ Recent posts