1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

 

2) 설명

삼성 기출인 것 같다. 시뮬레이션 문제..

톱니바퀴 4개를 두고 i번째 톱니를 시계방향 혹은 반시계방향으로 돌리는 문제다.

이때 1, 2, 3, 4 톱니들이 서로 맞물려 있는 바퀴의 값이 다를 때만 옆의 톱니바퀴를 반대방향으로 돌린다.

예를 들어 2번 톱니를 돌리는데 돌리기 전 1번, 2번 톱니가 맞물린 쪽이 S, N으로 다르다면 1번도 돌리고 S, S로 같다면 돌리지 않는다.

 

다 돌리고 나서 각 톱니의 12시 방향에 있는 값을 구하면 된다.

2. 풀이

1) 알고리즘

    : 시뮬레이션

 

2) 풀이 설명

톱니를 돌리는 걸 처음에 직접 구현하려다가 그냥 rotate 함수를 썼다.

사실 시뮬레이션 문제를 잘 안 풀어봐서 처음 써보다보니 음의 방향으로 돌리는 걸 v.begin()기준으로 해서 헷갈렸다.(v.end() 기준으로 해서 조금 더 간단하게 할 수 있었다)

어떤 톱니까지 돌릴지는 rotate 전에 diff라는 vector를 사용해서 미리 구했다.

그리고 diff에 체크된 배열들을 gear_idx 톱니(입력으로 돌리는 톱니)를 기준으로 왼쪽, 오른쪽으로 돌려나갔다.

 

3. 코드

더보기

 

#include <iostream>
#include <vector>
#include <algorithm>

#define N_GEAR 4
#define N_WHEEL 8

using namespace std;


int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int K, gear_idx, direction, answer = 0;
	vector<vector<bool>> gear(N_GEAR+1, vector<bool>(N_WHEEL, false));
	string input;
	for(int i=1;i<=N_GEAR;i++){
		cin >> input;
		for(int j=0;j<N_WHEEL;j++){
			gear[i][j] = input[j]=='0'? 0 : 1;
		}
	}

	cin >> K;
	vector<bool> diff(5, false);

	while(K--){
		cin >> gear_idx >> direction;
		
		fill(diff.begin(), diff.end(), false);
	
		int left_direction = -direction;
		int right_direction = -direction;

		for(int i=gear_idx+1;i<=N_GEAR;i++)
			diff[i] = gear[i][6] != gear[i-1][2];

		for(int i=gear_idx-1;i>0;i--)
			diff[i] = gear[i][2] != gear[i+1][6];
	
		rotate(gear[gear_idx].begin(), (direction==1? gear[gear_idx].end() - 1 : gear[gear_idx].begin() + 1), gear[gear_idx].end());

		for(int i=gear_idx+1;i<=N_GEAR && diff[i];i++, left_direction *= -1)
			rotate(gear[i].begin(), (left_direction==1? gear[i].end() - 1 : gear[i].begin() + 1), gear[i].end());

		for(int i=gear_idx-1;i>0 && diff[i];i--, right_direction *= -1)
			rotate(gear[i].begin(), (right_direction==1? gear[i].end() - 1 : gear[i].begin() + 1), gear[i].end());
	}
	vector<int> squared = {0, 1, 2, 4, 8};
	for(int i=1;i<=N_GEAR;i++){
		if(gear[i][0])
			answer += squared[i];
	}
	cout << answer << "\n";


	return 0;
}

 

4. 느낀점

 - 시뮬레이션은 단순한 개념을 깔끔하고 효율적으로 구현해내야 하는 게 중요한 것 같다

 - 단순해보인다고 냅다 구현하려다 보면 코드 더러워지면서 혼난다.. 내 코드다 많이 더러워서 나중에 다시 손봐야 할 것 같다..

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/1034] 램  (0) 2021.07.27
[BOJ/7579] 앱  (0) 2020.12.29
[백준/9656] 돌 게임 2  (0) 2020.11.02
[백준/2631] 줄세우기  (0) 2020.11.02
[백준/9252] LCS 2  (0) 2020.10.27

+ Recent posts