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

 

서론

시뮬레이션 문제.

시뮬레이션 문제는 정확한 문제 이해와 실수를 하지 않는게 정말 중요한데, 문제를 잘 못 이해했다.

모든 톱니바퀴가 돌기 전 상태에서 각각의 톱니바퀴 조건을 비교해야하는데, 1번 톱니바퀴가 회전하면 회전한 후의 상태로 조건을 비교해서 2번 톱니바퀴를 회전시키는 방식으로 이해했었다.

 


아이디어

회전할 톱니바퀴와 회전방향을 입력받으면 톱니바퀴들의 회전상태를 저장할 배열을 만든다.

회전할 톱니바퀴가 2번 톱니바퀴이고 회전방향이 오른쪽이라면

  1    

위와 같이 저장하고 오른쪽 톱니바퀴로 한칸씩 이동하며 회전가능한지 확인한다. 회전 가능하면 왼쪽 톱니바퀴의 -1을 곱한값을 입력한다. 회전할 수 없을때까지 반복한다.

  1 -1  

왼쪽도 마찬가지 방법으로 해준다.

-1 1 -1  

그 후 톱니바퀴들을 위 배열의 회전방향에 따라 회전시켜준다.

 

 

톱니바퀴의 회전은 톱니바퀴의 상태가 저장된 배열을 우측/좌측으로 한칸씩 이동시킨다. 

1 1 0 0 0 0 0 1

위 톱니바퀴의 시계방향 회전은 배열의 우측으로 한칸 이동이다.

1 1 1 0 0 0 0 0

 

톱니바퀴의 회전 가능여부를 확인하기 위해 현재 톱니바퀴와 오른쪽/왼쪽 톱니바퀴가 맞닿는곳을 비교하기 위해서는 두 톱니바퀴 배열의 칸을 직접 비교한다.

현재 톱니바퀴와 오른쪽 톱니바퀴의 비교는 현재 톱니바퀴의 3번째 칸과 오른쪽 톱니바퀴의 7번째 칸을 비교한다.

 


구현

//c++

#include <iostream>
#include <string>

using namespace std;

int wheel[4][8];
int dir[4];

void init() {
	for (int i = 0; i < 4; i++) {
		string tmp;
		cin >> tmp;
		for (int j = 0; j < 8; j++) {
			wheel[i][j] = tmp[j]-'0';
		}
	}
}

void rotation(int idx) {
	int tmp = wheel[idx][7];
	for (int i = 7; i > 0; i--) {
		wheel[idx][i] = wheel[idx][i - 1];
	}
	wheel[idx][0] = tmp;
}

void rRotation(int idx) {
	int tmp = wheel[idx][0];
	for (int i = 0; i < 7; i++) {
		wheel[idx][i] = wheel[idx][i + 1];
	}
	wheel[idx][7] = tmp;
}

void print() {
	int sum = 0;
	int plus = 1;
	for (int i = 0; i < 4; i++) {
		if (wheel[i][0] == 1) sum += plus;
		plus *= 2;
	}
	cout << sum;
}

int main() {
	init();

	int n;
	cin >> n;
	while (n--) {
		int idx, dirTmp;
		cin >> idx >> dirTmp;
		idx--;
		dir[idx] = dirTmp;

		for (int i = idx + 1; i < 4; i++) {
			if (wheel[i][6] == wheel[i - 1][2]) dir[i] = 0;
			else dir[i] = dir[i - 1] * -1;
		}
		
		for (int i = idx - 1; i >= 0; i--) {
			if (wheel[i][2] == wheel[i + 1][6]) dir[i] = 0;
			else dir[i] = dir[i + 1] * -1;
		}

		for(int i=0;i<4;i++) {
			if (dir[i] == 1) rotation(i);
			else if (dir[i] == -1) rRotation(i);
		}
	}

	print();


}