[BOJ] 14891 : 톱니바퀴

14891 : 톱니바퀴

풀이

시뮬레이션

배열을 계속회전시키는게아니라 간단하게 각 톱니바퀴의

왼쪽 idx, 오른쪽 idx를 저장하는 배열을 만들어서 관리했다.

g[4][2] 는 0~3번 톱니바퀴의 [0]:왼쪽접합점idx, [1]:오른쪽접함점idx이다.

(사실 한쪽+4하면 반대쪽이긴하다 이렇게하려면 +4했을때 8이상되면 -8하는 연산이 추가로 필요하다)

멋지게 함수도 만들고, 깔끔하게 풀고싶었으나,

회전이 연쇄적으로 될때 while로 idx를 수정한다음에 반복하도록 했다가 틀려버렸다.

그래서 ‘동시에’연쇄적으로 수정될 수 있도록 디버깅 하니까 4중 if문이 나오네 ㅎ_ㅎ;

이부분도 함수하나만들면 깔끔해질것 같다.

정말 빡구현이고 1시간반정도 걸렸지만, 생각한대로 코딩되었고, 괜찮은 문제인것 같다.

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;

int g[4][2] = { { 6,2 },{ 6,2 } ,{ 6,2 } ,{ 6,2 } };

int cal(int num,int dir) {
    num += dir;
    if (num == 8)
        return 0;
    else if (num == -1)
        return 7;
    else
        return num;
}

int main() {
    //n극:0, s극:1
    int arr[4][8];
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 8; j++) {
            scanf("%1d", &arr[i][j]);
        }
    }
    
    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
        //dir: (1,시계) (-1,반시계)
        int num, dir;
        cin >> num >> dir;
        num--;
        //원래는 시계방향이면 g원소값을 -1씩 한다
        //연계에서는 시계방향이면 반시계로 움직이므로 +1씩 한다
        int tmp = num;
        if (tmp>0){
            //먼저 돌리면 안된다!!! '동시애'회전한다!
            if (arr[tmp][g[tmp][0]] != arr[tmp-1][g[tmp - 1][1]]) {
                if (tmp - 1 > 0 && (arr[tmp-1][g[tmp - 1][0]] != arr[tmp - 2][g[tmp - 2][1]])) {
                    if (tmp - 2 > 0 && (arr[tmp - 2][g[tmp - 2][0]] != arr[tmp - 3][g[tmp - 3][1]])) {
                        g[tmp - 3][0] = cal(g[tmp - 3][0], dir);
                        g[tmp - 3][1] = cal(g[tmp - 3][1], dir);
                    }
                    g[tmp - 2][0] = cal(g[tmp - 2][0], -dir);
                    g[tmp - 2][1] = cal(g[tmp - 2][1], -dir);
                }
                g[tmp - 1][0] = cal(g[tmp - 1][0], dir);
                g[tmp - 1][1] = cal(g[tmp - 1][1], dir);
            }
        }
        tmp = num;
        if (tmp < 3) {
            if (arr[tmp][g[tmp][1]] != arr[tmp+1][g[tmp + 1][0]]){
                if (tmp + 1 < 3 && (arr[tmp+1][g[tmp+1][1]] != arr[tmp + 2][g[tmp + 2][0]])) {
                    if (tmp + 2 < 3 && (arr[tmp+2][g[tmp+2][1]] != arr[tmp + 3][g[tmp + 3][0]])) {
                        g[tmp + 3][0] = cal(g[tmp + 3][0], dir);
                        g[tmp + 3][1] = cal(g[tmp + 3][1], dir);
                    }
                    g[tmp + 2][0] = cal(g[tmp + 2][0], -dir);
                    g[tmp + 2][1] = cal(g[tmp + 2][1], -dir);
                }
                g[tmp + 1][0] = cal(g[tmp + 1][0], dir);
                g[tmp + 1][1] = cal(g[tmp + 1][1], dir);
            }
        }
        //num톱니바퀴 변경
        g[num][0] = cal(g[num][0], -dir);
        g[num][1] = cal(g[num][1], -dir);
    }
    int sum = 0;
    for (int i = 0; i < 4; i++) {
        int idx = g[i][1];
        for (int j = 0; j < 2; j++) {
            idx--;
            if (idx == -1)
                idx = 7;
        }
        if (arr[i][idx] == 1) {
            //2의 i-1승
            sum += pow(2, i);
        }
    }
    cout << sum;
    return 0;
}
Written on March 30, 2019