백준 14891 - 톱니바퀴

1 minute read

문제링크

문제설명

  • 링크 참고

문제접근

  • 회전시킬 톱니바퀴의 위치에 따라 연쇄적으로 영향을 받는 톱니바퀴들의 회전 방향이 달라진다.
  • 회전시키기 전 톱니바퀴가 겹치는 부분의 극성을 파악한다.
  • 회전된 톱니바퀴와 인접한 톱니바퀴가 영향을 받는 극성이라면 반대방향으로 회전시킨다.

구현

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <memory.h>

#define GEAR_MAX 4
#define ROT_STATUS 3
#define ELE_MAX 8
#define COUNTER_CLOCKWISE -1
#define CLOCKWISE 1
using namespace std;

vector<string> gear;
vector<pair<int, int>> rotateInfo;
vector<pair<int, int>> checkGear[ROT_STATUS];
bool rotStatus[ROT_STATUS];
int K;
int scores[4] = { 1, 2, 4, 8 };

void input()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	for (int i = 0; i < GEAR_MAX; i++) {
		string str;
		cin >> str;
		gear.push_back(str);
	}

	cin >> K;
	for (int i = 0; i < K; i++) {
		int num, dir;
		cin >> num >> dir;
		rotateInfo.push_back(make_pair(num, dir));
	}

	checkGear[0].push_back(make_pair(1, 2));
	checkGear[0].push_back(make_pair(2, 6));
	checkGear[1].push_back(make_pair(2, 2));
	checkGear[1].push_back(make_pair(3, 6));
	checkGear[2].push_back(make_pair(3, 2));
	checkGear[2].push_back(make_pair(4, 6));
}

void updateRotateStatus()
{
	for (int i = 0; i < ROT_STATUS; i++) {
		if (gear[checkGear[i][0].first - 1][checkGear[i][0].second] != gear[checkGear[i][1].first - 1][checkGear[i][1].second]) {
			rotStatus[i] = true;
		}
	}
}

void roateClockWise(int gearNum)
{
	string tmp = gear[gearNum];
	tmp = string(1, tmp.back()) + tmp;
	tmp.pop_back();
	gear[gearNum] = tmp;
}

void rotateCounterClockWise(int gearNum)
{
	string tmp = gear[gearNum];
	tmp.push_back(tmp.front());
	tmp = tmp.substr(1);
	gear[gearNum] = tmp;
}

void rotate(int gearNum, int dir)
{
	if (dir == COUNTER_CLOCKWISE) rotateCounterClockWise(gearNum);
	else if (dir == CLOCKWISE) roateClockWise(gearNum);
}

void controlRotation(int gearNum, int dir)
{
	memset(rotStatus, false, sizeof(rotStatus));
	updateRotateStatus();

	rotate(gearNum, dir);
	if (gearNum == 0) {
		if (rotStatus[0]) {
			rotate(1, -dir);
			if (rotStatus[1]) {
				rotate(2, dir);
				if (rotStatus[2]) rotate(3, -dir);
			}
		}
	}
	else if (gearNum == 1) {
		if (rotStatus[0]) rotate(0, -dir);
		if (rotStatus[1]) {
			rotate(2, -dir);
			if (rotStatus[2]) rotate(3, dir);
		}
	}
	else if (gearNum == 2) {
		if (rotStatus[2]) rotate(3, -dir);
		if (rotStatus[1]) {
			rotate(1, -dir);
			if (rotStatus[0]) rotate(0, dir);
		}
	}
	else if (gearNum == 3) {
		if (rotStatus[2]) {
			rotate(2, -dir);
			if (rotStatus[1]) {
				rotate(1, dir);
				if (rotStatus[0]) rotate(0, -dir);
			}
		}
	}
}

int calculateScore()
{
	int ret = 0;
	for (int i = 0; i < GEAR_MAX; i++) {
		if (gear[i][0] == '1') ret += scores[i];
	}
	return ret;
}

int solution()
{
	for (auto ele : rotateInfo) {
		controlRotation(ele.first - 1, ele.second);
	}
	return calculateScore();
}

int main()
{
	input();
	cout << solution() << endl;
	return 0;
}

Leave a comment