CLOCKSYNC (중하, p. 168)

문제#

image.png


어떻게 풀었나?#

동일 스위치를 4번이상 누르게 되는 경우, 한번도 누르지 않은 경우와 같으므로 각각의 스위치는 4번 이상 누르는 경우가 없다. 스위치를 누르는 순서와 상관없이 결과는 같기 때문에 순서는 중요하지 않다.

이 2가지만 생각할 수 있다면, 모든 스위치를 0~3번 눌러보는 모든 경우의 수는 $4^{10}$가지 존재 -> 따라서 완탐으로 풀면 된다.

책에는 난이도가 ‘중’으로 나와있지만, 중하 정도가 적당할 것 같다.


정답 코드#

#include <bits/stdc++.h>
using namespace std;
vector<int> sw[10] = {
    {0,1,2},
    {3,7,9,11},
    {4,10,14,15},
    {0,4,5,6,7},
    {6,7,8,10,12},
    {0,2,14,15},
    {3,14,15},
    {4,5,7,14,15},
    {1,2,3,4,5},
    {3,4,5,9,13}
};
int ck[16];
int mn_ans;
const int INF = 0x3f3f3f3f;

inline void Rotate(int x, int n) {
    ck[x]+=3*n;
    if(ck[x]>12) ck[x]-=12;
}

inline void RevRotate(int x, int n) {
    ck[x]-=3*n;
    if(ck[x]<=0) ck[x]+=12;
}

void Dfs(int x, int ans) {
    if(x==10) {
        int cnt=0;
        for(int i=0; i<16; i++) {
            if(ck[i]==12) cnt++;
        }
        if(cnt==16) mn_ans = min(mn_ans, ans);
        return;
    }

    for(int i = 0; i < 4; i++) {
        if(i > 0) {
            for(int ck_no : sw[x]) {
                Rotate(ck_no, i);
            }
        }
        Dfs(x+1,ans+i);
        if(i > 0) {
            for(int ck_no : sw[x]) {
                RevRotate(ck_no, i);
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int tc; cin >> tc;
    while(tc--) {
        mn_ans = INF;
        for(int i=0; i<16; i++) cin >> ck[i];
        Dfs(0,0);
        if(mn_ans == INF) puts("-1");
        else printf("%d\n", mn_ans);
    }
    return 0;
}