[SW Expert] [모의 SW 역량테스트] 4013번 특이한 자석 (Java)
Algorithm/SW Expert Academy

[SW Expert] [모의 SW 역량테스트] 4013번 특이한 자석 (Java)

728x90

SW Expert [모의 SW 역량테스트] 4013번 특이한 자석 :

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH

 

 

비트 마스크를 사용해서 풀어본 첫 문제다.

톱니바퀴의 정보를 입력받을 때 int형으로 입력받았고, 회전할 때는 시프트 연산자를 활용하여 회전하였다.

하지만... 굳이 비트 마스크를 사용할 필요가 있었을까 싶다.

정답을 맞힌 후에 다른 사람들의 코드를 보니 비트 마스크를 사용한 사람은 거의 없었다.

처음 사용해보는 개념이다 보니 익숙지 않았고, 시간도 꽤나 오래 걸렸다.

새로운 개념을 경험했다는 것에 의의를 두어야겠다.

 

인접 톱니바퀴를 회전할 때는 Queue를 사용했다.

입력받은 톱니바퀴를 Queue에 넣은 뒤, 다시 빼서 인접한 톱니바퀴가 회전해야 한다면 Queue에 넣어준다.

그러고 나서 뺀 톱니바퀴는 회전을 해준다.

여기서 주의할 점은 한 번 회전한 톱니바퀴는 boolean 배열로 체크를 해줘야 한다.

만약 체크를 하지 않는다면, 2번 이상 회전할 가능성이 있다.

 

 

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    private static int k, answer;
    private static int[] list, score = {1, 2, 4, 8};

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());

        for (int t = 1; t <= T; t++) {
            list = new int[5];
            k = Integer.parseInt(br.readLine());
            for (int i = 1; i <= 4; i++) { // 입력
                st = new StringTokenizer(br.readLine());
                for (int j = 1; j <= 8; j++) {
                    if (st.nextToken().equals("1"))
                        list[i] = list[i] + (1 << (8 - j));
                }
            }
            for (int i = 0; i < k; i++) {
                st = new StringTokenizer(br.readLine());
                int num = Integer.parseInt(st.nextToken());
                int dir = Integer.parseInt(st.nextToken());

                solution(num, dir);
            }

            answer = 0;
            for (int i = 1; i <= 4; i++) {
                int temp = (list[i] >> 7) & 1;
                if (temp == 1) answer += score[i - 1];
            }
            System.out.println("#" + t + " " + answer);
        }
    }

    private static void solution(int num, int dir) {
        Queue<Node> queue = new LinkedList<>();
        queue.add(new Node(num, dir));

        boolean[] visit = new boolean[5];
        visit[num] = true;

        int s, d;
        while (!queue.isEmpty()) {
            Node node = queue.poll();

            if (node.num > 1) { // 왼쪽 체크
                s = (list[node.num] >> 1) & 1;
                d = (list[node.num - 1] >> 5) & 1;
                if (s != d && !visit[node.num - 1]) {
                    queue.add(new Node(node.num - 1, node.dir * (-1)));
                    visit[node.num - 1] = true;
                }
            }
            if (node.num < 4) { // 오른쪽 체크
                s = (list[node.num] >> 5) & 1;
                d = (list[node.num + 1] >> 1) & 1;
                if (s != d && !visit[node.num + 1]) {
                    queue.add(new Node(node.num + 1, node.dir * (-1)));
                    visit[node.num + 1] = true;
                }
            }
            list[node.num] = rotate(list[node.num], node.dir);
        }
    }

    private static int rotate(int num, int dir) {
        switch (dir) {
            case 1: // 시계 방향
                if ((num & 1) == 1) num = (num >> 1) + 128;
                else num = num >> 1;
                break;
            case -1: // 반시계 방향
                if ((num >> 7) == 1) num = ((num << 1) + 1) & 255;
                else num = num << 1;
                break;
        }
        return num;
    }
}

class Node {
    int num, dir;
    
    public Node(int num, int dir) {
        this.num = num;
        this.dir = dir;
    }
}
728x90