문제 출처

1. 문제설명


  • 8개의 이빨을 가진 톱니바퀴가 있다.
  • 각 이빨은 12시 방향부터 시계방향으로 주어지며,
  • N 또는 S극을 가진다.
  • 시계 방향 또는 반시계 방향으로 회전한다.
    • 회전할 때, 같은 극이라면 회전하지 않는다.
    • 톱니가 회전되었다면, 같은 방향의 한칸 옆의 톱니도 영향을 받아 회전한다.
      • 극이 같으면 회전하지 않는다.
  • 톱니의 최종 상태를 구하라



2. 알고리즘 설계


  • 시뮬레이션 문제이다.
  • 극이 다르다면, 회전하는 로직(rotate)과, 한칸씩 밀어주는 shift함수를 구현해야한다.
  • rotate
    • 왼쪽 및 오른쪽 방향 중 극이 다른(회전할 수 있는) 톱니를 체크한다.
      • 왼쪽 : 톱니 2번째 index와 중심이 되는 톱니 6번째 index의 극이 같은지 체크
      • 오른쪽 : 톱니 6번째 index와 중심이 되는 톱니 2번째 index의 극이 같은지 체크
  • shift
    • 톱니의 index와 방향(dir)을 인자로 받는다.
    • 1인 경우(시계 방향) : for(int i=6; i>=0; i--) states[idx][i+1] = states[idx][i]
    • -1인 경우(반시계 방향) : for(int i=1; i<8; i++) states[idx][i-1] = states[idx][i]



3. 전체 코드


#include <bits/stdc++.h>
using namespace std;

string states[4];
int k, n, d, chk[4];

void shift(int idx, int dir) {
	if(dir == 1) {
		char first = states[idx][7];
		for(int i=6; i>=0; i--) states[idx][i+1] = states[idx][i];
		states[idx][0] = first;
	}

	else {
		char last = states[idx][0];
		for(int i=1; i<8; i++)
			states[idx][i-1] = states[idx][i];
		states[idx][7] = last;
	}
}

void rotate() {
	int left = n-1;
	int right = n+1;
	
	fill_n(&chk[0], 4, 0);
	chk[n] = d;

	// left의 끝까지 체크
	char cmp = states[n][6];
	int dir = d;
	while(left >= 0) {
		char cmp_left = states[left][2];
		if(cmp == cmp_left) break;

		dir *= -1;
		cmp = states[left][6];
		chk[left--] = dir;
	}

	//right의 끝까지 체크
	cmp = states[n][2];
	dir = d;
	while(right < 4) {
		char cmp_right = states[right][6];
		if(cmp == cmp_right) break;

		dir *= -1;
		cmp = states[right][2];
		chk[right++] = dir;
	}

	
	for(int i=0; i<4; i++)
		if(chk[i] != 0)
			shift(i, chk[i]);
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	for(int i=0; i<4; i++)
		cin >> states[i];

	cin >> k;
	while(k--) {
		cin >> n >> d;
		n--;

		rotate();
	}

	int ans = 0;
	int score[] = {1,2,4,8};
	for(int i=0; i<4; i++)
		if(states[i][0] == '1') ans += score[i];

	cout << ans;
    return 0;
}



4. 소감


  • 구현할 때 작은 실수들이 굉장히 많았던 문제
  • 중간 값을 출력해보면서 구현을 고쳐나갔다.
  • 알고리즘 문제를 풀 때 디버깅을 하는 것보다
  • 출력해보고 왜 이상하게 돌아가는지 확인하는 게 성장에 더 도움이 되는 거 같다!