https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
문제 이해
거의 그냥 시뮬레이션 문제인데, 내가 문제를 또 잘못봐서 한참을 헤맸다.
최종 점수를 판단하는 건 모든 cmd를 수행하고 난 후이다! 난 cmd를 한 번 실행할 때마다 점수가 나는 건줄 알았다...
cmd를 하나씩 수행할 때,
- 좌우에 다른 극인 자석이 있으면 걔네를 돌린다.
- visited 배열을 하나 두어서 이미 한번 돌렸던 애가 다시 돌아가지 않게 한다.
- 예를 들어 2번 자석이 돌아감 > 3번 자석 다른 극이라 돌아감 > 3번의 좌측인 2번 자석은 이미 움직였으므로 돌리지 않고, 우측인 4번 자석이 다른 극이면 움직인다.
- 당연히 이 visited 배열은 cmd하나 끝나면 초기화가 필요하다
자석이 도는 동작 자체는 배열을 한 칸씩 왼쪽 혹은 오른쪽으로 옮겨주면 된다.
이게 헷갈릴 수 있으니 단순 배열을 가지고 실험을 해보자.
작성 코드 (C)
#include <stdio.h>
int K;
int magnet[4+2][8+2];
int cmd[20][2]; //0: 자석 넘버, 1: 방향
int visited[4];
void getInput(void){
scanf("%d", &K);
for(int i = 0; i<4; i++){
for(int j = 0; j<8; j++){
scanf("%d", &magnet[i][j]);
}
}
for(int i = 0; i<K; i++){
scanf("%d %d", &cmd[i][0], &cmd[i][1]);
cmd[i][0]--;
}
}
void turn(int idx, int dir){
visited[idx] = 1;
// 옆에 자석 살피기
// 본인이 움직일 수 있는지 파악
if(idx-1 >= 0){
// 좌측에 자석 있음
if(magnet[idx][6] != magnet[idx-1][2]){
// 다른 극임 -> 돌아감
if(visited[idx-1] != 1) turn(idx-1, (-1)*dir);
}
}
if(idx+1 < 4){
// 우측에 자석 있음
if(magnet[idx][2] != magnet[idx+1][6]){
// 다른 극임 -> 돌아감
if(visited[idx+1] != 1) turn(idx+1, -dir);
}
}
// 자석 돌리기
if(dir == 1){ // 시계 방향일 경우
int tmp = magnet[idx][7];
for(int i = 7; i>=1; i--){
magnet[idx][i] = magnet[idx][i-1];
}
magnet[idx][0] = tmp;
}
if (dir == -1){ // 반시계 방향일 경우
int tmp = magnet[idx][0];
for(int i = 1; i<8; i++){
magnet[idx][i-1] = magnet[idx][i];
}
magnet[idx][7] = tmp;
}
//printf("turned magnet %d in %d direction\n", idx, dir);
}
int countPnt(void){
// 현재 자석 상태에서 포인트가 어떻게 나는지
int pnt = 0;
for(int i = 0; i<4; i++){
if(magnet[i][0] == 0) continue; // N극임, 점수 없음
else{
// S극임, 2^i 만큼의 점수를 얻는다.
pnt += (1 << i);
}
}
return pnt;
}
int Solve(void){
int pnt = 0;
for(int i = 0; i<K; i++){
// K번 만큼 돌림
turn(cmd[i][0], cmd[i][1]);
//printf("-----cmd %d done----\n", i);
for(int j = 0; j<4; j++) visited[j] = 0; // 초기화
}
// 회전 다 함
pnt = countPnt();
return pnt;
}
int main(void){
int T, ans;
scanf("%d", &T);
for(int i = 0; i<T; i++){
getInput();
ans = Solve();
printf("#%d %d\n", i+1, ans);
}
return 0;
}
'컴퓨터기본 > 문제풀이' 카테고리의 다른 글
[SWEA] 5644. 무선 충전 (0) | 2021.10.09 |
---|---|
[SWEA] 4014. 활주로 건설 (0) | 2021.10.09 |
[정올] 2893 : 제리의 치즈먹기 (Cheese) (0) | 2021.10.09 |
[SWEA] 2383. 점심 식사시간 (0) | 2021.10.09 |
[백준] 2477번: 참외밭 (2) | 2021.09.26 |