반응형
[모의 SW 역량테스트] 특이한 자석
1. 이해하기
- 4개의 자석이 있고, 각 자석은 8개의 날을 가지고 있다.
- 자석의 각 날 마다 N극 또는 S극의 자성을 가지고 있다.
- 하나의 자석이 1 칸 회전될 때, 붙어 있는 자석은 서로 붙어 있는 날의 자성과 다를 경우에만 인력에 의해 반대 방향으로 1칸 회전된다.
- 모든 회전이 끝난 후, 아래와 같은 방법으로 점수를 계산한다.
- 1 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0점, S 극이면 1점을 획득한다.
- 2 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0점, S 극이면 2점을 획득한다.
- 3 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0점, S 극이면 4점을 획득한다.
- 4 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0점, S 극이면 8점을 획득한다.
- 자석을 K번 회전시킨 후 점수의 총 합을 구하는 문제.
- 시뮬레이션 문제.
2. 구현하기
-
자석을 시계방향, 반 시계방향으로 회전시켰을 때, 자석의 모양을 구현한다.
void rotate_clockwise(int num) { int t = magnetic[num][0]; for(int i = 8; i > 1; i--) { magnetic[num][i%8] = magnetic[num][i-1]; } magnetic[num][1] = t; } void rotate_anticlockwise(int num) { int t = magnetic[num][0]; for(int i = 0; i < 7; i++) { magnetic[num][i] = magnetic[num][i+1]; } magnetic[num][7] = t; }
-
현재 주어진 번호의 왼쪽, 오른쪽으로 가면서 자석이 붙어있는 날이 다른 극을 가지고 있는지 확인한다. 이 때, 다르다면 탐색을 멈춘다.
void get_left_diff(vector<INF>& inf, int num, int dir) { int n_dir = -dir; for(int i = num; i-1 >= 0; i--) { if(magnetic[i-1][2] == magnetic[i][6]) break; inf.push_back({i-1,n_dir}); n_dir = -n_dir; } } void get_right_diff(vector<INF>& inf, int num, int dir) { int n_dir = -dir; for(int i = num; i+1 < 4; i++) { if(magnetic[i+1][6] == magnetic[i][2]) break; inf.push_back({i+1,n_dir}); n_dir = -n_dir; } }
-
어느 번호의 자석을 돌려야 할 지 구한 것을 바탕으로 회전을 시킨다.
void rotate(vector<INF>& inf) { int size = inf.size(); for(int i = 0; i < size; i++) { INF now = inf[i]; if(now.dir == 1) rotate_clockwise(now.num); else rotate_anticlockwise(now.num); } } void simulate() { for(int k = 0; k < K; k++) { int num,dir; cin >> num >> dir; num--; vector<INF> inf; inf.push_back({num,dir}); get_left_diff(inf,num,dir); get_right_diff(inf,num,dir); rotate(inf); } }
-
K번 회전시킨 후, 점수를 구한다.
int get_score() { int ret = 0; for(int i = 0; i < 4; i++) { ret += magnetic[i][0]*(1<<i); } return ret; }
3. 전체 코드
#include <iostream>
#include <vector>
using namespace std;
struct INF{
int num,dir;
};
int magnetic[4][8];
int K;
void rotate_clockwise(int num) {
int t = magnetic[num][0];
for(int i = 8; i > 1; i--) {
magnetic[num][i%8] = magnetic[num][i-1];
}
magnetic[num][1] = t;
}
void rotate_anticlockwise(int num) {
int t = magnetic[num][0];
for(int i = 0; i < 7; i++) {
magnetic[num][i] = magnetic[num][i+1];
}
magnetic[num][7] = t;
}
int get_score() {
int ret = 0;
for(int i = 0; i < 4; i++) {
ret += magnetic[i][0]*(1<<i);
}
return ret;
}
void rotate(vector<INF>& inf) {
int size = inf.size();
for(int i = 0; i < size; i++) {
INF now = inf[i];
if(now.dir == 1) rotate_clockwise(now.num);
else rotate_anticlockwise(now.num);
}
}
void get_left_diff(vector<INF>& inf, int num, int dir) {
int n_dir = -dir;
for(int i = num; i-1 >= 0; i--) {
if(magnetic[i-1][2] == magnetic[i][6]) break;
inf.push_back({i-1,n_dir});
n_dir = -n_dir;
}
}
void get_right_diff(vector<INF>& inf, int num, int dir) {
int n_dir = -dir;
for(int i = num; i+1 < 4; i++) {
if(magnetic[i+1][6] == magnetic[i][2]) break;
inf.push_back({i+1,n_dir});
n_dir = -n_dir;
}
}
void simulate() {
for(int k = 0; k < K; k++) {
int num,dir;
cin >> num >> dir;
num--;
vector<INF> inf;
inf.push_back({num,dir});
get_left_diff(inf,num,dir);
get_right_diff(inf,num,dir);
rotate(inf);
}
}
void input() {
cin >> K;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 8; j++) {
cin >> magnetic[i][j];
}
}
}
int main() {
int T;
cin >> T;
for(int t = 1; t <= T; t++) {
input();
simulate();
cout << '#' << t << ' ' << get_score() << '\n';
}
return 0;
}
'알고리즘 > SW Expert Academy' 카테고리의 다른 글
[모의 SW 역량테스트] 4008. 숫자 만들기 (0) | 2019.10.18 |
---|---|
[모의 SW 역량테스트] 4012. 요리사 (0) | 2019.10.18 |
[모의 SW 역량테스트] 4014. 활주로 건설 (0) | 2019.10.17 |
[모의 SW 역량테스트] 2117. 홈 방범 서비스 (0) | 2019.10.17 |
[모의 SW 역량테스트] 2112. 보호 필름 (0) | 2019.10.17 |