[BOJ] 14891번 : 톱니바퀴
2024. 8. 21. 18:24ㆍAlgorithm
1. problem :
https://www.acmicpc.net/problem/14891
2. solution 1 :
#include <bits/stdc++.h>
using namespace std;
string board[4];
int K; // Test case의 수
deque<char> dq1;
deque<char> dq2;
deque<char> dq3;
deque<char> dq4;
void rotate(int w,deque<char>& dq) {
if (w == 1) {
dq.push_front(dq.back());
dq.pop_back();
}
if (w == -1) {
dq.push_back(dq.front());
dq.pop_front();
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
for (int i = 0; i < 4; i++) cin >> board[i];
cin >> K;
while (K--) {
int numth,clock_way;
cin >> numth >> clock_way;
numth--;
int isvis[4] = {};
int clock_arr[4] = {};
clock_arr[numth] = clock_way; // 첫번째 인덱스와 방향 기록
isvis[numth] = 1;
queue<int> Q;
Q.push(numth);
while (!Q.empty()) {
int cur = Q.front(); Q.pop();
if (clock_arr[cur] == 0) continue;
if (cur >= 1 && !isvis[cur - 1]) {
if (board[cur][6] != board[cur - 1][2]) {
clock_arr[cur - 1] = -clock_arr[cur];
Q.push(cur - 1);
}
isvis[cur - 1] = 1;
}
if (cur + 1 < 4 && !isvis[cur + 1]) {
if (board[cur][2] != board[cur + 1][6]) {
clock_arr[cur + 1] = -clock_arr[cur];
Q.push(cur + 1);
}
isvis[cur + 1] = 1;
}
}
dq1.clear();
dq2.clear();
dq3.clear();
dq4.clear();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 8; j++) {
if (i == 0) dq1.push_back(board[i][j]);
if (i == 1) dq2.push_back(board[i][j]);
if (i == 2) dq3.push_back(board[i][j]);
if (i == 3) dq4.push_back(board[i][j]);
}
}
if (clock_arr[0] != 0) rotate(clock_arr[0], dq1);
if (clock_arr[1] != 0) rotate(clock_arr[1], dq2);
if (clock_arr[2] != 0) rotate(clock_arr[2], dq3);
if (clock_arr[3] != 0) rotate(clock_arr[3], dq4);
for (int j = 0; j < 8; j++) {
board[0][j] = dq1[j];
board[1][j] = dq2[j];
board[2][j] = dq3[j];
board[3][j] = dq4[j];
}
}
int sum = 0;
for (int i = 0; i < 4; i++) {
if (board[i][0] == '1') sum += (1 << i);
}
cout << sum << '\n';
}
deque를 따로 4개 선언을 하다 보니, 코드가 비효율적이다.
3. solution 2 :
#include <bits/stdc++.h>
using namespace std;
int K; // Test case의 수
deque<char> gears[4]; // 4개의 톱니바퀴를 각각 deque로 관리
void rotate(int w, deque<char>& dq) {
if (w == 1) { // 시계 방향 회전
dq.push_front(dq.back());
dq.pop_back();
} else if (w == -1) { // 반시계 방향 회전
dq.push_back(dq.front());
dq.pop_front();
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
for (int i = 0; i < 4; i++) {
string s;
cin >> s;
gears[i] = deque<char>(s.begin(), s.end()); // string을 deque로 변환
}
cin >> K;
while (K--) {
int numth, clock_way;
cin >> numth >> clock_way;
numth--; // 0-indexing으로 맞추기
int clock_arr[4] = {}; // 각 톱니바퀴의 회전 방향을 기록
clock_arr[numth] = clock_way;
// 각 톱니바퀴의 회전 여부와 방향을 결정하는 BFS
queue<int> Q;
Q.push(numth);
while (!Q.empty()) {
int cur = Q.front();
Q.pop();
// 왼쪽 톱니바퀴와의 비교
if (cur > 0 && clock_arr[cur - 1] == 0) {
if (gears[cur][6] != gears[cur - 1][2]) {
clock_arr[cur - 1] = -clock_arr[cur]; // 반대 방향으로 회전
Q.push(cur - 1);
}
}
// 오른쪽 톱니바퀴와의 비교
if (cur < 3 && clock_arr[cur + 1] == 0) {
if (gears[cur][2] != gears[cur + 1][6]) {
clock_arr[cur + 1] = -clock_arr[cur]; // 반대 방향으로 회전
Q.push(cur + 1);
}
}
}
// 모든 톱니바퀴에 대해 결정된 방향으로 회전 수행
for (int i = 0; i < 4; i++) {
if (clock_arr[i] != 0) {
rotate(clock_arr[i], gears[i]);
}
}
}
// 최종 결과 계산
int sum = 0;
for (int i = 0; i < 4; i++) {
if (gears[i][0] == '1') sum += (1 << i);
}
cout << sum << '\n';
}
deque를 배열로 만든 케이스이다. chatgpt의 코드다.
4. solution 3 :
// Authored by : jihwan0123
// Co-authored by : BaaaaaaaaaaarkingDog
// http://boj.kr/dfcfa653b8494b3082959f248edfb200
#include <bits/stdc++.h>
using namespace std;
string board[4];
// x : 번호, dir : 방향, 1번의 회전을 처리하는 함수
void go(int x, int dir) {
int dirs[4] = {};
dirs[x] = dir;
// 왼쪽으로 회전을 전파
int idx = x;
while (idx > 0 && board[idx][6] != board[idx-1][2]){
dirs[idx-1] = -dirs[idx];
idx--;
}
// 오른쪽으로 회전을 전파
idx = x;
while (idx < 3 && board[idx][2] != board[idx+1][6]){
dirs[idx+1] = -dirs[idx];
idx++;
}
for(int i = 0; i < 4; i++) {
if(dirs[i] == -1)
rotate(board[i].begin(), board[i].begin()+1, board[i].end());
else if(dirs[i] == 1)
rotate(board[i].begin(), board[i].begin()+7, board[i].end());
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
for (int i = 0; i < 4; i++) cin >> board[i];
int k;
cin >> k;
while (k--) {
int x, dir;
cin >> x >> dir;
go(x - 1, dir);
}
int ans = 0;
for (int i = 0; i < 4; i++)
if (board[i][0] == '1') ans += (1 << i);
cout << ans;
}
/*
STL에 rotate 함수가 있어서 회전을 다소 편하게 처리할 수 있다.
*/
source code 출처 : https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x0D/solutions/14891.cpp
basic-algo-lecture/0x0D/solutions/14891.cpp at master · encrypted-def/basic-algo-lecture
바킹독의 실전 알고리즘 강의 자료. Contribute to encrypted-def/basic-algo-lecture development by creating an account on GitHub.
github.com
stl에 있는 rotate 함수가 쓰였다. 또한 , go라는 함수가 톱니바퀴의 값을 바꾸는 로직이 신기하다.
'Algorithm' 카테고리의 다른 글
| [BOJ] 13335번 : 트럭 (0) | 2024.08.22 |
|---|---|
| [BOJ] 14499번 : 주사위 굴리기 (0) | 2024.08.22 |
| [BOJ] 11559번 : Puyo Puyo (0) | 2024.08.21 |
| [BOJ] 15686번 : 치킨 배달 (0) | 2024.08.20 |
| [BOJ] 12100번 : 2048 (Easy) (0) | 2024.08.20 |