BOJ 14891 : 톱니바퀴 - C++

김정욱·2021년 3월 31일
0

Algorithm - 문제

목록 보기
197/249

톱니바퀴

코드

#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <deque>
#include <numeric>
#define ll long long
using namespace std;
// 01:37 ~ 02:24
int K;
vector<pair<int,int>> v;
deque<int> cycle[4];
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    for(int i=0;i<4;i++)
    {
        string s;
        cin >> s;
        for(auto a : s)
            cycle[i].push_back(a-'0');
    }
    cin >> K;
    for(int i=0;i<K;i++)
    {
        int a, b;
        cin >> a >> b;
        v.push_back({a-1,b}); // 톱니 번호, 방향
    }
    // 2번, 6번 톱니를 확인해야 함
    for(int i=0;i<v.size();i++)
    {
        int ch = v[i].first;
        int dir = v[i].second;
        /* 바뀌기 전에 left, right 저장 */
        int ch_left = cycle[ch][6];
        int ch_right = cycle[ch][2];
        /* 선택된 톱니 회전 */
        if(dir == -1){
            int tmp = cycle[ch].front();
            cycle[ch].pop_front();
            cycle[ch].push_back(tmp);
        }else{
            int tmp = cycle[ch].back();
            cycle[ch].pop_back();
            cycle[ch].push_front(tmp);
        }
        int cur_dir = dir*(-1); // 영향받은 톱니가 움직여야 하는 방향
        /* 선택 이전 톱니 회전 */
        for(int a=ch-1;a>=0;a--)
        {
            if(cycle[a][2] == ch_left){
                // 같으면 톱니가 움직이지 않으므로 그 뒤 톱니를 할 필요도 X
                break;
            }else{
                // 다음 톱니에 영향을 주는 톱니 값은 바뀌기 전 값
                ch_left = cycle[a][6];
                // 다를 때 움직이는데, 반시계이면 
                if(cur_dir == -1){
                    int tmp = cycle[a].front();
                    cycle[a].pop_front();
                    cycle[a].push_back(tmp);
                }else{
                    int tmp = cycle[a].back();
                    cycle[a].pop_back();
                    cycle[a].push_front(tmp);
                }
                cur_dir *= -1; // 다음 영향 받는 방향 변경
            }
        }
        cur_dir = dir*(-1);
        /* 선택 이후 톱니 회전 */
        for(int b=ch+1;b<4;b++)
        {
            if(cycle[b][6] == ch_right){
                // 같으면 톱니가 움직이지 않으므로 그 뒤 톱니를 할 필요도 X
                break;
            }else{
                // 다음 톱니에 영향을 주는 톱니 값은 바뀌기 전 값
                ch_right = cycle[b][2];
                // 다를 때 움직이는데, 반시계이면 
                if(cur_dir == -1){
                    int tmp = cycle[b].front();
                    cycle[b].pop_front();
                    cycle[b].push_back(tmp);
                }else{
                    int tmp = cycle[b].back();
                    cycle[b].pop_back();
                    cycle[b].push_front(tmp);
                }
                cur_dir *= -1; // 다음 영향 받는 방향 변경
            }
        }
    }
    int ans = cycle[0][0]*1 + cycle[1][0]*2 + cycle[2][0]*4 + cycle[3][0]*8;
    cout << ans;
    return 0;
}
  • 핵심
    : 회전하기 전 상태에서 톱니left, right저장해서 갱신해줘야 함
    (코드에서는 순차적으로 처리하지만, 실제로는 동시일어나는 일이기 때문)
profile
Developer & PhotoGrapher

0개의 댓글