코딩테스트/Java

[JAVA] 백준 톱니바퀴

SK_MOUSE 2021. 7. 6. 14:31

구현문제이다.

실수한점 : input값을 받을때, 띄어쓰기가 되어있지 않기 때문에 StringTokenizer로 끊어서 값을 받을수 없는데 인지하지 못하여 조금 헤맸다.

첫번째 테스트케이스 예시

Circular Queue가 먼저 생각이 났다.

 

하지만 Queue를 직접 Push, POP을 이용하는 경우에는 비효율적일거라고 생각했다.

 

그래서 배열값을 넣어두고 각 위치에 해당하는 주소값을 뜻하는 index를 정하였다.

 

아래는 Circular Queue를 포인터처럼 표현 식이다.

생성자는 input값으로 받은 value값을 받아낸다.

class Circular {
    int right = 2;//3시방향
    int left = 6;//9시방향
    int[] states = new int[8];

    Circular(int[] states) {
        for (int i = 0; i < this.states.length; i++) {
            this.states[i] = states[i];
        }
    }
}

이를 통해 최종 결과값을 불러오는데 필요한 top값은 right-2 또는 left+2값으로 나타내었다.

 


-시작지점으로부터 왼쪽, 오른쪽으로 각각 쭉 진행해나가야된다는점 때문에 goLeft(), goRight() 메소드를 따로 구현했다.

 

- 그리고 goRotate를 통해서 처음값은 반드시 회전시키도록하였다.

 

- 각각 오른쪽 왼쪽에 대하여 끝값이 아니면 goLeft(), goRight()를 호출하여 각각 재귀를 끝까지 돌고나서 끝에서부터 회전시키며 return되는 방식으로 구현했다.


아래는 전체 코드이다.

import java.io.*;
import java.util.*;

class Main {
    static int[] rotateCnum;
    static int[] rotateCdir;
    static Circular[] cu = new Circular[4];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        for (int i = 0; i < 4; i++) {
            int[] states = new int[8];
            String s = br.readLine();
            for (int j = 0; j < 8; j++) {
                states[j] = Integer.parseInt(String.valueOf(s.charAt(j)));
            }
            cu[i] = new Circular(states);
        }

        int kF = Integer.parseInt(br.readLine());
        rotateCnum = new int[kF];
        rotateCdir = new int[kF];
        for (int k = 0; k < kF; k++) {
            st = new StringTokenizer(br.readLine());
            rotateCnum[k] = Integer.parseInt(st.nextToken()) - 1;
            rotateCdir[k] = Integer.parseInt(st.nextToken());
        }

        for (int i = 0; i < rotateCnum.length; i++) {
            goRotate(rotateCnum[i], rotateCdir[i]);
        }

        int result = 0;
        for (int i = 0; i < 4; i++) {
            if (cu[i].getResult()) {
                result += Math.pow(2, i);
            }
        }
        System.out.println(result);
    }

    static void goRotate(int circleOrder, int circleDir) {
        if (circleOrder != 0) goLeft(circleOrder - 1, -circleDir);//왼쪽이 반대방향으로 도느냐
        if (circleOrder != 3) goRight(circleOrder + 1, -circleDir);
        if (circleDir == 1) {
            cu[circleOrder].timeShift();
        } else {
            cu[circleOrder].reverseTimeShift();
        }
    }

    static void goLeft(int circleOrder, int circleDir) {
        if (circleDir == 1) {//시계방향
            if (circleOrder >= 0 && cu[circleOrder].getRight() != cu[circleOrder + 1].getLeft()) {//왼쪽방향 재귀확인
                if (circleOrder > 0) goLeft(circleOrder - 1, -circleDir);//
                cu[circleOrder].timeShift();
            }

        } else {//반시계방향
            if (circleOrder >= 0 && cu[circleOrder].getRight() != cu[circleOrder + 1].getLeft()) {//왼쪽방향 재귀확인
                if (circleOrder > 0) goLeft(circleOrder - 1, -circleDir);
                cu[circleOrder].reverseTimeShift();
            }
        }
    }

    static void goRight(int circleOrder, int circleDir) {
        if (circleDir == 1) {//시계방향
            if (circleOrder < 4 && cu[circleOrder].getLeft() != cu[circleOrder - 1].getRight()) {//왼쪽방향 재귀확인
                if (circleOrder < 3) goRight(circleOrder + 1, -circleDir);
                cu[circleOrder].timeShift();
            }

        } else {//반시계방향
            if (circleOrder < 4 && cu[circleOrder].getLeft() != cu[circleOrder - 1].getRight()) {//왼쪽방향 재귀확인
                if (circleOrder < 3) goRight(circleOrder + 1, -circleDir);
                cu[circleOrder].reverseTimeShift();
            }
        }
    }
}

class Circular {
    int right = 2;
    int left = 6;
    int[] states = new int[8];

    Circular(int[] states) {
        for (int i = 0; i < this.states.length; i++) {
            this.states[i] = states[i];
        }
    }

    int getRight() {
        return states[right];
    }

    int getLeft() {
        return states[left];
    }

    void timeShift() {
        right = right - 1;
        if (right < 0) right = 7;
        left = left - 1;
        if (left < 0) left = 7;
    }

    void reverseTimeShift() {
        right = right + 1;
        if (right > 7) right = 0;
        left = left + 1;
        if (left > 7) left = 0;
    }

    boolean getResult() {
        int top = right - 2;//열두시방향
        if (top < 0) top += 8;//mod
        if (states[top] == 1) return true;

        return false;
    }
}

 

다른사람 코드(실행속도는 같은데 코드길이가 짧아서 가져왔다.)

import java.io.*;
import java.util.*;

public class Main {
    static int[][] gears;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        gears = new int[4][8];
        for(int i=0; i<4; i++){
            String gear = br.readLine();
            for(int j=0; j<8; j++){
                gears[i][j] = gear.charAt(j)-'0';
            }
        }

        int k = Integer.parseInt(br.readLine());
        for(int i=0; i<k; i++){
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            int s = Integer.parseInt(st.nextToken())-1;
            int turn = Integer.parseInt(st.nextToken());

            func(s,turn,0);
        }

        int ans=0;
        if(gears[0][0]==1) ans+=1;
        if(gears[1][0]==1) ans+=2;
        if(gears[2][0]==1) ans+=4;
        if(gears[3][0]==1) ans+=8;
        System.out.println(ans);
    }
    static void func(int idx, int turnd, int d){
        if(d==0){
            if(idx-1>=0 && gears[idx][6] != gears[idx-1][2]){
                func(idx-1, -turnd, 1);
            }
            if(idx+1<4 && gears[idx][2] != gears[idx+1][6]){
                func(idx+1, -turnd, 2);
            }
        }
        else if(d==1){
            if(idx-1>=0 && gears[idx][6] != gears[idx-1][2]){
                func(idx-1, -turnd, 1);
            }
        }else if(d==2){
            if(idx+1<4 && gears[idx][2] != gears[idx+1][6]){
                func(idx+1, -turnd, 2);
            }
        }

        if(turnd==-1){
            int tmp = gears[idx][0];
            for(int i=0; i<7; i++){
                gears[idx][i] = gears[idx][i+1];
            }
            gears[idx][7]=tmp;
        }else if(turnd==1){
            int tmp = gears[idx][7];
            for(int i=7; i>=1; i--){
                gears[idx][i] = gears[idx][i-1];
            }
            gears[idx][0]=tmp;
        }

    }
}
반응형