[伯俊]ギアJAVA


質問する


合計8個のギアの4個が一列に並んでいて、下図のようになっています.また、鋸歯はN極またはS極のいずれかを表す.ギアはナンバー、一番左のギアは1番、右のギアは2番、右のギアは3番、一番右のギアは4番です.

このとき、ギアは常にK回回転します.歯車の回転は一節に準ずる.回転は時計回りと反時計回りがあり、下図のように回転します.


ギアを回転させるには、回転するギアと回転の方向を決めなければなりません.ギアが回転すると、互いに接触する極に応じて隣のギアを回転させてもよいし、回転させなくてもよい.ギアAを回転させる際に、その隣のギアBと互いに接触するギアの極性が異なると、BはAの回転方向とは逆になる.例えば、以下の状況を見てみましょう.

2つのギアの噛み合い部分は緑色の破線で縛られた部分です.ここで、ギア3ポチを反時計回りに回すと、ギア4ポチが時計回りに回ります.2番ギアの噛み合い部分がS極なので回転せず、1番ギアは2番が回転していないので回転しません.したがって、下図のような形状が作成されます.

上記の状態では、1番ギアを時計回りに回転させ、2番ギアを反時計回りに回転させ、2番ギアを回転させるので、3番も同時に時計回りに回転させます.4番は3番回転ですが、接触が極めて同じなので回転しません.このため、次の状態になります.

ギアの初期状態とギアの回転方法を指定する場合は、最終ギアの状態を求めるプログラムを作成します.

入力


1行目は1番ギアの状態、2行目は2番ギアの状態、3行目は3番ギアの状態、4行目は4番ギアの状態を示します.状態は8個の整数からなり,12時方向から時計回りに与えられる.Nは極めて0,Sは極めて1である.
5行目は回転数K(1≦K≦100)を与える.次のK行は順番に回転の方法を与えます.各方法は2つの整数からなり、第1の整数は回転歯車の番号であり、第2の整数は方向である.方向が1の場合は時計回り、-1の場合は反時計回りです.

しゅつりょく


合計K回回転した後、4個のギアの積分の和を出力します.点数は次のように計算されます.
  • 1号ギヤ12点方向N極0点、S極1点
  • 番歯車12点方向N極0点、S極2点
  • 3号ギヤ12点方向N極0点、S極4点
  • 4号ギヤ12点方向N極0点、S極8点
  • 問題を解く

  • 先時計回りに回転するとき
  • 反時計回り回転時
  • はギアの変化を表す
  • である.
    public static void rotate(int[] spins, int state) {
        if (state == 1) { // 시계방향
    
            int temp = spins[7];
    
            for (int i = 7; i > 0; i--) {
                spins[i] = spins[i - 1];
            }
    
            spins[0] = temp;
    
        } else { // 반시계 방향
    
            int temp = spins[0];
    
            for (int i = 0; i < 7; i++) {
                spins[i] = spins[(i + 1)];
            }
    
            spins[7] = temp;
        }
    }
    上記
  • が完了する後、
  • .
  • 右左歯車が
  • 回転するかどうかを検査し探索する.
    for (int i = 0; i < K; i++) {
        in = br.readLine().split(" ");
        N = Integer.parseInt(in[0]) - 1;
        S = Integer.parseInt(in[1]); // 1시게 -1 반시계 // 0 멈춤
    
        Arrays.fill(v, false);
        queue.clear();
        queue.offer(new int[]{N, S});
        v[N] = true;
    
        int[] cur;
        while (!queue.isEmpty()) {
            cur = queue.poll();
    
            int nx;
            for (int d = 0; d < 2; d++) {
                nx = cur[0] + dx[d];
    
                if (nx < 0 || nx > 3) continue;
                if (v[nx]) continue;
                v[nx] = true;
                //왼쪽일 떄
                if (d == 0) {
                    if (spins[nx][2] == spins[cur[0]][6]) continue;
                    queue.offer(new int[]{nx, -cur[1]});
                } else {//오른쪽 일 떄
                    if (spins[nx][6] == spins[cur[0]][2]) continue;
                    queue.offer(new int[]{nx, -cur[1]});
                }
            }
    
            rotate(spins[cur[0]], cur[1]);
        }
    }
  • 最後に、ギアスコアを保存して、答えに出力します.
  • for (int i = 0; i < 4; i++) {
        answer += (spins[i][0] << i);
    }
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Main {
    
        static int[] dx = {-1, 1};
    
        public static void main(String[] args) throws Exception {
    
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
            // 톱니바퀴
            int[][] spins = new int[4][8];
            int answer = 0;
            String[] in;
    
            for (int i = 0; i < 4; i++) {
                in = br.readLine().split("");
                for (int j = 0; j < 8; j++) {
                    spins[i][j] = Integer.parseInt(in[j]);
                }
            }
    
    
            // 회전 횟수
            int K = Integer.parseInt(br.readLine());
    
            int N;
            int S;
    
            boolean[] v = new boolean[4];
            Queue<int[]> queue = new LinkedList<>();
    
            for (int i = 0; i < K; i++) {
                in = br.readLine().split(" ");
                N = Integer.parseInt(in[0]) - 1;
                S = Integer.parseInt(in[1]); // 1시게 -1 반시계 // 0 멈춤
    
                Arrays.fill(v, false);
                queue.clear();
                queue.offer(new int[]{N, S});
                v[N] = true;
    
                int[] cur;
                while (!queue.isEmpty()) {
                    cur = queue.poll();
    
                    int nx;
                    for (int d = 0; d < 2; d++) {
                        nx = cur[0] + dx[d];
    
                        if (nx < 0 || nx > 3) continue;
                        if (v[nx]) continue;
                        v[nx] = true;
                        //왼쪽일 떄
                        if (d == 0) {
                            if (spins[nx][2] == spins[cur[0]][6]) continue;
                            queue.offer(new int[]{nx, -cur[1]});
                        } else {//오른쪽 일 떄
                            if (spins[nx][6] == spins[cur[0]][2]) continue;
                            queue.offer(new int[]{nx, -cur[1]});
                        }
                    }
    
                    rotate(spins[cur[0]], cur[1]);
                }
            }
    
    
            for (int i = 0; i < 4; i++) {
                answer += (spins[i][0] << i);
            }
    
            System.out.println(answer);
    
        }
    
    
        public static void rotate(int[] spins, int state) {
            if (state == 1) { // 시계방향
    
                int temp = spins[7];
    
                for (int i = 7; i > 0; i--) {
                    spins[i] = spins[i - 1];
                }
    
                spins[0] = temp;
    
            } else { // 반시계 방향
    
                int temp = spins[0];
    
                for (int i = 0; i < 7; i++) {
                    spins[i] = spins[(i + 1)];
                }
    
                spins[7] = temp;
            }
        }
    }