본문 바로가기
Study/알고리즘 문제해결전략(종만북)

[종만북] CLOCKSYNC - Synchronizing Clocks (자바 java)

by Nahwasa 2023. 3. 20.

알고리즘 문제해결전략(종만북) 스터디 메인 페이지

문제 : aoj-CLOCKSYNC

 

 

풀이

  시계 자체에 초점을 맞추면 답이 안나온다. 스위치가 10개 밖에 없다는 부분에 초점을 맞춰보자. 결국 시계는 4번 돌면 제자리다.

 

  따라서 각 10개의 스위치는 3번 이상 누를 일이 없고, 그럼 O(C x 4^10)으로 처리가 가능함을 알 수 있다. 즉, 시계가 몇칸인지는 상관 없고, 그냥 스위치가 10개이고 각각 최대 3번까지 누를 수 있으니 4x4x... 를 해주면 되는 것이다. 

 

 

코드 : github

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static final int[][] MAPPING = {
            {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}
    };
    private static int[] clocks = new int[16];
    private int min;

    public static void main(String[] args) throws Exception {
        Main main = new Main();
        int c = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        while (c-->0) {
            sb.append(main.solution()).append('\n');
        }
        System.out.print(sb);
    }

    private int solution() throws Exception {
        setupClocks();
        synchronizeClocks(0, 0);

        return min == Integer.MAX_VALUE ? -1 : min;
    }

    private void setupClocks() throws IOException {
        StringTokenizer st = new StringTokenizer(br.readLine());
        min = Integer.MAX_VALUE;

        for (int i = 0; i < 16; i++) {
            clocks[i] = Integer.parseInt(st.nextToken());
        }
    }

    private void synchronizeClocks(int cnt, int mappingIdx) {
        if (mappingIdx == 10) {
            if (min > cnt && isAllClocks12()) {
                min = cnt;
            }
            return;
        }

        synchronizeClocks(cnt, mappingIdx+1);
        for (int i = 1; i <= 3; i++) {
            pressSwitch(mappingIdx, i, true);
            synchronizeClocks(cnt+i, mappingIdx+1);
            pressSwitch(mappingIdx, i, false);
        }
    }

    private void pressSwitch(int mappingIdx, int nth, boolean isClockwise) {
        for (int i = 0; i < MAPPING[mappingIdx].length; i++) {
            if (isClockwise) {
                clocks[MAPPING[mappingIdx][i]] += 3 * nth;
                if (clocks[MAPPING[mappingIdx][i]] > 12)
                    clocks[MAPPING[mappingIdx][i]] -= 12;
            } else {
                clocks[MAPPING[mappingIdx][i]] -= 3 * nth;
                if (clocks[MAPPING[mappingIdx][i]] <= 0)
                    clocks[MAPPING[mappingIdx][i]] += 12;
            }
        }
    }

    private boolean isAllClocks12() {
        for (int i = 0; i < 16; i++) {
            if (clocks[i] != 12) return false;
        }
        return true;
    }
}

 

 

※ 종만북에 이미 풀이가 있는데 제 풀이를 올리는 이유는 제가 책의 풀이를 보지 않고 문제를 푼 후 제 풀이를 올리고 나서 책의 풀이를 보는 방식으로 풀어보고 싶기 때문입니다.

댓글