ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4013. [모의 SW 역량테스트] 특이한 자석 - 자바(JAVA)
    알고리즘/SW Expert Academy 2022. 5. 30. 00:01
    728x90

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

     

    SW Expert Academy

    SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

    swexpertacademy.com

     

    문제 해석

    특이한 자석 4개가 존재하며 8개의 날을 가지고 있습니다.

    자석의 각 날마다 N극 또는 S극을 가지고 있으며 자석을 일렬로 배치되어 있습니다.

     

     

    자석에는 규칙이 존재합니다.

    서로 붙어있는 날의 자성이 다를 경우 인력에 의해 반대 방향으로 1칸 회전됩니다.

     

    특이한점은 회전하면서 검사하는것이 아니라 어떤 자석이 회전하기 전에 인접하여있는 극들이 같은지 아닌지 검사하고 극이 같다면 회전하지 않고 다르면 어떤 자석이 반대방향으로 회전합니다.

     

     

    문제 풀이 전 설계

    각 자석에 대한 정보를 가지고 있습니다.

    8짜리 배열으로 가지고 있어도 상관없을것 같습니다.

     

    이후에 특정 자석이 회전할때 양옆의 자석을 검사합니다.

    이후 회전이 일어나고 이것을 반복합니다.

     

    1. 특정 자석을 기준으로 돌릴 수 있는 모든 자석을 검사합니다.

    2. 양옆의 자석을 돌릴 수 있다면 반시계방향으로 돌려줍니다. (배열돌리기 + dfs)

     

    코드

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.StringTokenizer;
    
    public class Solution_4013_특이한자석 {
        static final int MAGNET_COUNT = 4;
        static final int EDGE = 8;
        static final int TOP = 0;
        static int[][] magnets = new int[MAGNET_COUNT + 1][EDGE];
        static boolean[] visited;
        static boolean[] checkDoRotate;
        static int dx[] = {-1, 1};
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int T = Integer.parseInt(br.readLine());
    
            StringBuilder sb = new StringBuilder();
            StringTokenizer st = null;
            for (int tc = 1; tc <= T; tc++) {
                int result = 0;
                int rotateCount = Integer.parseInt(br.readLine());
    
                for (int i = 1; i <= MAGNET_COUNT; i++) {
                    st = new StringTokenizer(br.readLine(), " ");
                    for (int j = 0; j < EDGE; j++) {
                        magnets[i][j] = Integer.parseInt(st.nextToken());
                    }
                }
                //입력 끝
    
                for (int i = 0; i < rotateCount; i++) {
                    st = new StringTokenizer(br.readLine(), " ");
                    int magnetNum = Integer.parseInt(st.nextToken());
                    int direction = Integer.parseInt(st.nextToken());
                    //자석회전
                    visited = new boolean[MAGNET_COUNT + 1];
                    checkDoRotate = new boolean[MAGNET_COUNT + 1];
                    checkRotate(magnetNum);
                    //System.out.println(Arrays.toString(checkDoRotate));
                    rotateMagnets(magnetNum, direction);
                }
    
                for (int i = 1; i <= MAGNET_COUNT; i++) {
                    //2^0 =1, 2^1=2 , 2^2= 4, 2^3 = 8
                    result += (magnets[i][TOP] * Math.pow(2, i - 1));
                }
    
                sb.append("#" + tc + " " + result + "\n");
            }
    
            System.out.println(sb.toString());
        }
    
        private static void checkRotate(int magnetNum) {
            //현재 자석은 회전할 수 있음
            checkDoRotate[magnetNum] = true;
    
            // 현재 자석에서 오른쪽을 검사
            for (int i = magnetNum; i <= MAGNET_COUNT - 1; i++) {
                if (magnets[i][2] != magnets[i + 1][6]) {
                    checkDoRotate[i + 1] = true;
                } else {
                    break;
                }
    
            }
    
            // 현재 자석에서 왼쪽으로
            for (int i = magnetNum; i > 1; i--) {
                if (magnets[i][6] != magnets[i - 1][2]) {
                    checkDoRotate[i - 1] = true;
                } else {
                    break;
                }
            }
        }
    
        private static void rotateMagnets(int magnetNum, int direction) {
            //해당 magnetNum을 우선 direction으로 회전
            visited[magnetNum] = true;
            rotate(magnetNum, direction);
    
            //양옆에 존재하는 자석들을 반시계방향으로 회전시킴
            for (int k = 0; k < 2; k++) {
                int nx = magnetNum + dx[k];
                //자석의 index가 유효해야 하며, 방문되지 않았어야 하며, 초기에 서로 극이 달라야 함.
                if (!isValid(nx)) {
                    continue;
                }
                rotateMagnets(nx, direction * -1);
            }
        }
    
        private static void rotate(int magnetNum, int direction) {
            //시계방향
            if (direction == 1) {
                int temp = magnets[magnetNum][EDGE - 1];
                for (int i = EDGE - 1; i > 0; i--) {
                    magnets[magnetNum][i] = magnets[magnetNum][i - 1];
                }
                magnets[magnetNum][0] = temp;
                return;
            }
    
            //반시계방향
            int temp = magnets[magnetNum][0];
            for (int i = 0; i < EDGE - 1; i++) {
                magnets[magnetNum][i] = magnets[magnetNum][i + 1];
            }
            magnets[magnetNum][EDGE - 1] = temp;
    
    
        }
    
    
        private static boolean isValid(int nx) {
            return nx >= 1 && nx <= MAGNET_COUNT && !visited[nx] && checkDoRotate[nx];
        }
    
    }

     

    댓글

Designed by Tistory.