본문 바로가기

알고리즘/백준

[백준] 14891번 톱니바퀴

반응형

14891번 톱니바퀴


1. 이해하기

  • 톱니바퀴가 서로 맞닿은 극에 따라서 옆에 있는 톱니바퀴를 회전시킬 수 있다.
    • 옆에 있는 톱니바퀴를 회전시키는 경우는 맞닿은 극이 서로 다를 경우에 반대 방향으로 회전하게 된다.
  • 톱니바퀴를 회전시킨 방법이 주어졌을 때, 최종 톱니바퀴의 상태를 구하는 문제.
  • 시뮬레이션 문제.

2. 구현하기

  • 톱니바퀴를 시계방향 혹은 반시계방향으로 회전시킨다.

    void rotate(int n, int dir) {
        if(dir == 1) {
            char temp = gear[n][7];
            for(int i = 7; i > 0; i--) {
                gear[n][i] = gear[n][i-1];
            }
            gear[n][0] = temp;
        } else if(dir == -1) {
            char temp = gear[n][0];
            for(int i = 0; i < 7; i++) {
                gear[n][i] = gear[n][i+1];
            }
            gear[n][7] = temp;
        }
    }
  • 특정 번째 톱니바퀴를 회전시키면서 양 옆에 있는 톱니바퀴도 회전시켜야 하는지 살펴본다.

    void simulate(int n, int dir) {
        vector<INF> v;
        v.push_back({n,dir});
        int n_dir = dir;
        for(int i = n; i+1 < 4; i++) {
            if(gear[i][2] == gear[i+1][6]) break;
            n_dir = (n_dir==1)?-1:1;
            v.push_back({i+1,n_dir});
        }
        n_dir = dir;
        for(int i = n; i-1 >= 0; i--) {
            if(gear[i][6] == gear[i-1][2]) break;
            n_dir = (n_dir==1)?-1:1;
            v.push_back({i-1,n_dir});
        }
    
        int size = v.size();
        for(int i = 0; i < size; i++) {
            rotate(v[i].n,v[i].dir);
        }
    }
  • 최종 톱니바퀴 상태를 보고 점수를 구한다.

    int get_score() {
        int ret = 0;
        for(int i = 0; i < 4; i++) {
            if(gear[i][0] == '1') ret += (1<<i);
        }
        return ret;
    }

3. 전체 코드

#include <iostream>
#include <vector>
using namespace std;
struct INF{
    int n,dir;
};
string gear[4];

void rotate(int n, int dir) {
    if(dir == 1) {
        char temp = gear[n][7];
        for(int i = 7; i > 0; i--) {
            gear[n][i] = gear[n][i-1];
        }
        gear[n][0] = temp;
    } else if(dir == -1) {
        char temp = gear[n][0];
        for(int i = 0; i < 7; i++) {
            gear[n][i] = gear[n][i+1];
        }
        gear[n][7] = temp;
    }
}

void simulate(int n, int dir) {
    vector<INF> v;
    v.push_back({n,dir});
    int n_dir = dir;
    for(int i = n; i+1 < 4; i++) {
        if(gear[i][2] == gear[i+1][6]) break;
        n_dir = (n_dir==1)?-1:1;
        v.push_back({i+1,n_dir});
    }
    n_dir = dir;
    for(int i = n; i-1 >= 0; i--) {
        if(gear[i][6] == gear[i-1][2]) break;
        n_dir = (n_dir==1)?-1:1;
        v.push_back({i-1,n_dir});
    }

    int size = v.size();
    for(int i = 0; i < size; i++) {
        rotate(v[i].n,v[i].dir);
    }
}

int get_score() {
    int ret = 0;
    for(int i = 0; i < 4; i++) {
        if(gear[i][0] == '1') ret += (1<<i);
    }
    return ret;
}

int main() {
    for(int i = 0; i < 4; i++) cin >> gear[i];
    int k;
    cin >> k;
    for(int i = 0; i < k; i++) {
        int n,dir;
        cin >> n >> dir;
        n--;
        simulate(n,dir);
    }
    cout << get_score() << '\n';
    return 0;
}

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 15684번 사다리 조작  (0) 2019.10.07
[백준] 15683번 감시  (0) 2019.10.06
[백준] 14890번 경사로  (0) 2019.10.05
[백준] 14889번 스타트와 링크  (0) 2019.10.04
[백준] 14888번 연산자 끼워넣기  (0) 2019.10.04