CS/Algorithm

[SWEA][C++] 4013 특이한 자석

별토끼. 2018. 12. 27. 14:51
반응형

[SWEA][C++] 4013 특이한 자석

 

문제

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH&categoryId=AWIeV9sKkcoDFAVH&categoryType=CODE

 

풀이

회전 시작 톱니에서 다른 톱니들과 맞물리는 점들을 확인했습니다. 그리고 조건에 충족하여 움직여야 한다면 rotation함수로 넘어가도록 설계했어요. 톱니가 움직인 뒤에 다른 톱니를 고려하면 안되기 때문에 톱니를 실제 움직이는 것은 마지막에 했습니다. 다음에는 cstdio를 이용해서 출력을 해봐야겠어요! 시간 단축하는 법을 스를 익혀야할 것 같아요.

 

코드

#include <iostream>
#include <math.h>
using namespace std;

void rotation(int gear_num, int direction, int* visited);
int* left_rotate(int* gear);
int* right_rotate(int* gear);
int** gear;
int** r;
int visited[5];

int main() {
    int T;
    cin >> T;
    for (int t = 1; t <= T; t++) {
        int K;
        //회전 갯수
        cin >> K;
        r = new int*[K];
        gear = new int*[5];
        for (int i = 1; i < 5; i++) {
            gear[i] = new int[9];
        }
        //자성정보
        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= 8; j++) {
                int tmp;
                cin >> tmp;
                gear[i][j] = tmp;
            }
        }
        // 회전 정보 입력 : 자석 번호, 회전 방향
        for (int k = 0; k < K; k++) {
            r[k] = new int[2];
            cin >> r[k][0] >> r[k][1];
        }

        //회전 시키기
        for (int k = 0; k < K; k++) {
            fill_n(visited, 5, 0);
            rotation(r[k][0], r[k][1], visited);
        }
        int result = 0;
        for (int i = 1; i <= 4; i++) {
            if (gear[i][1] != 0) {
                result += pow(2,i-1);
            }
        }
        cout <<"#"<< t << " " << result <<'\n';
        
    }
}

void rotation(int gear_num, int direction, int* visited) {
    visited[gear_num] = 1;
    //왼쪽톱니 움직이기
    if (gear_num > 1 && visited[gear_num-1] == 0) {
        if (gear[gear_num][7] != gear[gear_num - 1][3]) {
            int next_dir = -1;
            if (direction == next_dir) {
                next_dir = 1;
            }
            rotation(gear_num-1, next_dir, visited);
        }
    }
    //오른쪽톱니 움직이기
    if (gear_num < 4 && visited[gear_num+1] == 0) {
        if (gear[gear_num][3] != gear[gear_num + 1][7]) {
            int next_dir = -1;
            if (direction == next_dir) {
                next_dir = 1;
            }
            rotation(gear_num+1, next_dir, visited);
        }
    }
    //현재 톱니 회전시키기
    if (direction == 1) {
        gear[gear_num] = right_rotate(gear[gear_num]);
    }
    else
        gear[gear_num] = left_rotate(gear[gear_num]);
}

//왼쪽으로 회전
int* left_rotate(int* gear) {
    int first = gear[1];
    for (int i = 2; i < 9; i++) {
        gear[i - 1] = gear[i];
    }
    gear[8] = first;
    return gear;
}

//오른쪽으로 회전
int* right_rotate(int* gear) {
    int last = gear[8];
    for (int i = 7; i >=0; i--) {
        gear[i+1] = gear[i];
    }
    gear[1] = last;
    return gear;
}

 

반응형