백준의 톱니바퀴(14891) 문제이다.
( 문제 바로가기 )
[ 문제설명 ]
- 입력으로 4개의 톱니바퀴의 상태가 주어진다. 각 톱니바퀴는 총 8개의 날을 가지고 있으며 가로로 일직선으로 4개가 놓여져
있다. (톱니바퀴에는 N극과 S극이 있다.)
- 그리고 톱니바퀴를 회전시킬 명령어의 갯수와, 몇 번 톱니바퀴를 어떤 방향으로 돌릴지에 대한 정보가 입력으로 주어진다.
- 서로 이웃한 톱니바퀴(i-1 과 i와 i+1 번 톱니바퀴는 서로 이웃한 톱니바퀴) 의 맞닿은 부분이 같은 극이라면 이웃한 톱니바퀴
는 움직이지 않지만, 다른 극이라면 돌리는 톱니바퀴의 반대방향으로 톱니바퀴가 돌아가게된다.
- 명령어의 갯수만큼 톱니바퀴를 돌린 후, 4개의 톱니바퀴의 12시 방향에 있는 극이 S극이면 각각의 점수를 부여 받게 되고
그 점수를 출력하면 되는 문제이다.
[ 문제풀이 ]
1. 알고리즘에서 시뮬레이션은 정말 문제에서 주어진 조건 대로 그대로 구현을 하기만 하면 된다. 이 문제도 그대로 하면 된다.
2. 먼저 본인은 문제에서 사용되는 4개의 톱니바퀴를 Vector로 관리하였다. 입력으로 주어지는 톱니바퀴 4개의 상태를
Vector에 넣어주었다. Vector<int> Wheel[4] 이렇게 선언해놓고, 각각의 톱니바퀴의 상태를 관리하였다.
(톱니바퀴 번호가 1,2,3,4번이 아닌 0,1,2,3번으로 관리하였음 !)
3. 주어지는 명령어들도 Vector로 관리하였다. (본인이 Vector가 편해서 이렇게 관리했다는 거지, 꼭 이렇게 해야되는것이
아니다.) 명령어들의 vector는 2개의 int형을 pair로 관리하였으며, (명령을 수행할 대상 톱니바퀴의번호 , 회전시킬방향)
이렇게 2개의 데이터를 관리하였다.
3-1) 4개의 톱니바퀴를 vector로 관리하였다고 했는데, 톱니바퀴의 12시방향부터 시계방향으로 값을 넣어주었다.
그렇게 되면 톱니바퀴의 12시방향에 있는 값이 vector의 0번, 그 다음번이 1번... 이런식으로 가장 마지막 값은
7번이 되도록 관리하였다.
3-2) 3-1)처럼 관리하게 되면, 서로 이웃한 톱니바퀴를 쉽게 파악할 수 있다.
A번 톱니바퀴를 기준으로 설명하자면, A번의 2번 극과, A+1번의 6번극이 서로 맞닿은 극이 되며,
A번의 6번 극과, A-1번의 2번극이 서로 맞닿은 극이 된다. [ 그림참고 ]
그림과 같이 밑에 크게 검은글씨로 적힌 0,1,2,3은 톱니바퀴의 번호이고, 작은 빨강글씨로 적힌 0~7의 숫자는
각 톱니바퀴 안에서 배정받은 Index번호이다.
4. 톱니바퀴가 4개밖에 되지 않으므로 모든 경우에 대해서 다 구현해주었다.
1) 명령을 수행할 톱니바퀴의 번호가 0번일 경우
1. 0번의 2번 날과, 1번의 6번날을 비교. 만약 다르다면
2. 1번의 2번 날과, 2번의 6번날을 비교. 만약 다르다면
3. 2번의 1번 날과, 3번의 6번날을 비교. 만약 다르다면
0번 2번 톱니바퀴는 명령어가 지시한 방향으로, 1번 3번 톱니바퀴는 지시한 반대방향으로 돌려주었다.
위에서 말한 '만약 다르다면' 이라는 조건과 달리, 같아지는 구간이 있다면, 그 이후는 비교해 주지 않아도 된다.
만약 0번의 2번 날과 1번의 6번 날이 다르고, 1번의 2번날과 2번의 6번날이 서로 같다고 생각해보자.
1번은 0번과 맞닿은 극이 서로 다르기 때문에 돌아가야 하지만, 2번은 1번과 같기 때문에 움직이지 않아도 된다.
자연스럽게 2번이 움직이지 않으므로 3번 톱니바퀴도 움직이지 않아도 된다.
예를들어 명령을 수행할 톱니바퀴가 0번일 경우에 대해서만 설명을 했는데, 나머지 톱니바퀴도 저런식으로 비교해 주면
된다. 나머지 부분에 대해서는 소스코드를 참고해보자.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | #include<iostream> #include<vector> #include<string> #define endl "\n" using namespace std; int K; vector<int> Wheel[4]; vector<pair<int, int>> Cmd; void Input() { for (int i = 0; i < 4; i++) { string Inp; cin >> Inp; for (int j = 0; j < Inp.length(); j++) { int Tmp = Inp[j] - '0'; Wheel[i].push_back(Tmp); } } // 1은 시계방향 -1은 반시계방향 cin >> K; for (int i = 0; i < K; i++) { int Num, Dir; cin >> Num >> Dir; Num = Num - 1; Cmd.push_back(make_pair(Num, Dir)); } } int Reverse_Direction(int d) { if (d == 1) return -1; else return 1; } void Actual_Turning(int n, int d) { if (d == 1) { int Tmp = Wheel[n].at(7); for (int i = 7; i > 0; i--) { Wheel[n].at(i) = Wheel[n].at(i - 1); } Wheel[n].at(0) = Tmp; } else if (d == -1) { int Tmp = Wheel[n].at(0); for (int i = 0; i < 7; i++) { Wheel[n].at(i) = Wheel[n].at(i + 1); } Wheel[n].at(7) = Tmp; } } void Turn_Wheel(int n, int d) { int nd = Reverse_Direction(d); if (n == 0) { if (Wheel[n].at(2) != Wheel[n + 1].at(6)) { if (Wheel[n + 1].at(2) != Wheel[n + 2].at(6)) { if (Wheel[n + 2].at(2) != Wheel[n + 3].at(6)) { Actual_Turning(n, d); Actual_Turning(n + 1, nd); Actual_Turning(n + 2, d); Actual_Turning(n + 3, nd); } else { Actual_Turning(n, d); Actual_Turning(n + 1, nd); Actual_Turning(n + 2, d); } } else { Actual_Turning(n, d); Actual_Turning(n + 1, nd); } } else { Actual_Turning(n, d); } } else if (n == 1) { if (Wheel[n].at(6) != Wheel[n-1].at(2)) { Actual_Turning(n - 1, nd); } if (Wheel[n].at(2) != Wheel[n + 1].at(6)) { if (Wheel[n + 1].at(2) != Wheel[n + 2].at(6)) { Actual_Turning(n, d); Actual_Turning(n + 1, nd); Actual_Turning(n + 2, d); } else { Actual_Turning(n, d); Actual_Turning(n + 1, nd); } } else { Actual_Turning(n, d); } } else if (n == 2) { if (Wheel[n].at(2) != Wheel[n + 1].at(6)) { Actual_Turning(n + 1, nd); } if (Wheel[n].at(6) != Wheel[n - 1].at(2)) { if (Wheel[n - 1].at(6) != Wheel[n - 2].at(2)) { Actual_Turning(n, d); Actual_Turning(n - 1, nd); Actual_Turning(n - 2, d); } else { Actual_Turning(n, d); Actual_Turning(n - 1, nd); } } else { Actual_Turning(n, d); } } else if (n == 3) { if (Wheel[n].at(6) != Wheel[n - 1].at(2)) { if (Wheel[n - 1].at(6) != Wheel[n - 2].at(2)) { if (Wheel[n - 2].at(6) != Wheel[n - 3].at(2)) { Actual_Turning(n, d); Actual_Turning(n - 1, nd); Actual_Turning(n - 2, d); Actual_Turning(n - 3, nd); } else { Actual_Turning(n, d); Actual_Turning(n - 1, nd); Actual_Turning(n - 2, d); } } else { Actual_Turning(n, d); Actual_Turning(n - 1, nd); } } else { Actual_Turning(n, d); } } } void Solution() { for (int i = 0; i < Cmd.size(); i++) { int N = Cmd[i].first; int D = Cmd[i].second; Turn_Wheel(N, D); } int Answer = 0; if (Wheel[0].at(0) == 1) Answer = Answer + 1; if (Wheel[1].at(0) == 1) Answer = Answer + 2; if (Wheel[2].at(0) == 1) Answer = Answer + 4; if (Wheel[3].at(0) == 1) Answer = Answer + 8; cout << Answer << endl; } void Solve() { Input(); Solution(); } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글
[ 백준 2455 ] 지능형 기차 (C++) (0) | 2018.12.09 |
---|---|
[ 백준 14503 ] 로봇 청소기 (C++) (2) | 2018.12.09 |
[ 백준 14442 ] 벽 부수고 이동하기2 (C++) (0) | 2018.12.09 |
[ 백준 5014 ] 스타트링크 (C++) (0) | 2018.12.09 |
[ 백준 15661] 링크와 스타트 (C++) (2) | 2018.12.07 |