얼레벌레

[C++] 백준 #14891 톱니바퀴 본문

Coding/코딩테스트 준비

[C++] 백준 #14891 톱니바퀴

__Lucie__ 2022. 7. 29. 21:55

문제 링크

https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴

www.acmicpc.net

풀이

문제가 하라는대로 하면 풀 수 있는 문제다. (내기준)

오늘 에이블스쿨에서 코드를 짤 때 생각안하고 그냥 짜지말고

생각 -> (그래프나 도표 - 생략 가능) -> 슈도코드 -> 코드

이 순서로 짜면 잘 된다고 배웠는데, (사실 평소에도 이렇게 생각하긴 했지만 문제 풀 때 당황해서 맨날 '생각 -> 코드'가 되어버림;)

문제가 쉬운 것도 있겠지만, 실제로 저 순서로 짜보니 잘 짜졌다.

 

처음 생각할 땐 앞에서부터 비교해야 한다고 생각했는데,

나중에 보니 사용자가 입력한 톱니바퀴 번호부터 시작해 앞으로/뒤로 이동하며 톱니바퀴가 돌아갈 방향을 정해주어야 한다.

1. 4개의 톱니바퀴의 상태 배열 gear을 전역으로 선언했다.

gear 배열은 string 배열인데, 숫자가 공백 없이 들어오기 때문에 string으로 선언했다.

2. 그리고 어떤 톱니바퀴를 어느 방향으로 돌릴 것인지를 K개 입력받는데, 입력받을 때마다 톱니바퀴가 돌아가는 방향을 가리키는 direction 배열을 새로 만들었다. (입력받을 때마다 direction 배열이 초기화될 수 있게끔)

3. 또한, 입력받을 때마다 setDirection 함수로 각 톱니바퀴들의 회전 방향을 정해주고 나서 rotate 함수로 실제 회전을 시켜줬다. clockwise와 counterclock함수는 rotate 함수 내에서 호출되는데, gear의 원소들을 하나씩 앞으로 당기거나(반시계 방향 회전을 구현), 뒤로 미는(시계방향 회전을 구현) 역할을 한다.

 

함수 설명

1. main: 메인에서 4개의 톱니바퀴 정보와, 회전할 톱니바퀴 번호와 회전 방향을 K번 입력받는다. 이 K번 입력받을 때 setDirection함수와 rotate 함수가 호출된다.

2. setDirection 함수: 메인함수로부터 회전할 톱니바퀴의 인덱스와 각 톱니바퀴들의 회전 방향 정보가 들어가 있는 direction 배열을 받는다. 그 다음 while문을 활용해 회전을 시작하는 톱니바퀴의 앞/뒤 톱니들의 direction 정보를 바꿔준다.(direction 배열은 0으로 초기화 했음) 

3. rotate 함수: setDirection 함수에서 설정한 direction 배열을 바탕으로 실제 회전을 진행한다. 이 때 clockwise 함수와 counterclock 함수를 이용한다.

//
// Created by ღ 𝚂𝚑𝚒𝚗𝚎 𝚈𝚎𝚘𝚗 ღ on 2022/07/29.
//

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
string gear[4];
int score[4] = {1, 2, 4, 8};
int K;

void clockwise(int x) {
    string tmp[4];
    for(int i=0; i<4; i++){
        tmp[i] = gear[i];
    }

    for(int j=0; j<7; j++){
        gear[x][j+1] = tmp[x][j];
    }
    gear[x][0] = tmp[x][7];


}

void counterclock(int x) {
    string tmp[4];
    for(int i=0; i<4; i++){
        tmp[i] = gear[i];
    }

    for(int j=0; j<7; j++){
        gear[x][j] = tmp[x][j+1];
    }
    gear[x][7] = tmp[x][0];

}

void setDirection(int which, int (&direction)[4]) {
    int tmp = which;
    while(tmp+1 < 4) { //뒤로 가면서 뒤의 톱니바퀴 회전 방향 바꿈
        if(gear[tmp][2] == gear[tmp+1][6]) //바로 뒤의 톱니바퀴와 극이 같다면 더이상 뒤로 갈 필요 없음
            break;
        else {
            direction[tmp+1] = direction[tmp] * (-1); //바로 뒤의 톱니바퀴와 극이 다르다면 방향 전환해야 함
            tmp++;
        }
    }
    
    //앞으로 갈 때도 마찬가지
    tmp = which;
    while(tmp-1>=0) {
        if(gear[tmp][6] == gear[tmp-1][2])
            break;
        else{
            direction[tmp-1] = direction[tmp]*(-1);
            tmp--;
        }
    }
}

void rotate(const int (&direction)[4]) {
    for(int i=0; i<4; i++){
        if(direction[i] == -1){
            counterclock(i);
        }
        else if(direction[i] == 1) {
            clockwise(i);
        }
        else
            continue;
    }
}


int main(){
    for(int i=0; i<4; i++){
        cin>>gear[i];
    }
    cin>>K;
    for(int i=0; i<K; i++){
        int which, dir;
        cin>>which>>dir;
        int direction[4] = {0, };
        direction[which-1] = dir;
        setDirection(which-1, direction);
        rotate(direction);
    }
    int answer = 0;
    for(int i=0; i<4; i++){
        if(gear[i][0] == '1')
            answer+=score[i];
    }
    cout<<answer<<"\n";


}

14891 결과

'Coding > 코딩테스트 준비' 카테고리의 다른 글

[C++] 백준 #1654 랜선자르기  (0) 2022.08.04
[C++] 백준 #15683 감시  (0) 2022.08.01
[C++] 백준 - #14890 경사로  (0) 2022.07.28
[C++] 백준 #14503 로봇청소기  (0) 2022.07.28
[C++] 백준 #14499 주사위 굴리기  (0) 2022.07.26