[SWEA 4013] 특이한 자석 (JAVA)

teethh_j·2022년 4월 13일
0

Problem Solving

목록 보기
7/14

🔰 문제


SW Expert Academy 4013번: 특이한 자석 (모의 SW 역량)


💡 접근방식


단순 구현, 시뮬레이션 문제
이동할 자석 번호와 이동 방향이 주어지면

  1. 입력으로 주어진 자석 기준으로 좌측, 우측으로 쭉 뻗어나가면서 맞물린 자석의 극에 따라 회전 방향 세팅 (-1: 반시계, 1: 시계, 0: 회전X)
  2. 회전 세팅이 끝나면 각 자석 별로 회전 방향에 따라 회전 시작

💦 풀면서 실수, 놓친 점


헷갈리는 건 아니고, 배열 당기는 방식이 바로 떠오르지 않고 고민했다가 떠올려서 다시 정리해보았다. 이는 시뮬레이션 문제에서 자주 볼 수 있는 것으로 바로 떠오르게 공부하자,,

시계방향 이동 = 배열 한칸씩 오른쪽으로 이동
1. 기존 배열 복사. (기존 배열: origin, 복사 배열: copy)
2. 모든 요소에 대해

origin[i] = copy[(i-1+N)%N]

실시 (오른쪽으로 이동한다는 것은 기존 배열의 왼쪽 값을 끌고 오는 것이기 때문)

반시계 방향 이동 = 배열 한칸씩 왼쪽으로 이동
1. 기존 배열 복사. (기존 배열: origin, 복사 배열: copy)
2. 모든 요소에 대해

origin[i] = copy[(i+1+N)%N]

실시 (왼쪽으로 이동한다는 것은 기존 배열의 오른쪽 값을 끌고 오는 것이기 때문)


단순히 +1, -1만 하는 것이 아닌 뒤에 +N을 더해주고 전체값을 %N을 하는 이유는 양 끝값 때문이다. 예를 들어 `1 2 3 4 5`를 `5 1 2 3 4`로 바꾼다고 가정하면, 배열을 오른쪽으로 이동시키는 것이다. 모든 요소에 대해 왼쪽 거를 끌고 오면 될 거 같지만 새로 만들어지는 배열의 0번째 요소는 기존 배열의 N-1번째 요소를 갖고와야 한다. 그러기 위해선 `i(0)-1+N`을 실행해줘야 한다. 이를 양 끝값에만 따로 코드를 적용하려면 코드 가독성이 떨어지므로 모든 요소에 대해 `i-1+N`을 해주는 것이고, `%N을 하는 이유는 index가 out of range되지 않기 위해` 나눠주는 것이다.

🕑 소요시간

40분

💻 풀이


import java.io.*;
import java.util.*;

// SEA / 특이한 자석 / 모의 SW 역량
// https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeV9sKkcoDFAVH
public class Solution_4013 {
	static int K;
	static int res; // 회전이 끝난 후 획득 점수
	static int magnet[][];
	static int dir[];

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for (int t = 1; t <= T; t++) {
			res = 0;
			K = Integer.parseInt(br.readLine());
			magnet = new int[5][8]; // 1~4번까지의 n극, s극 저장
			dir = new int[5]; // 1~4번의 회전 방향 (0: 회전 x, -1: 반시계, 1: 시계)
			for (int i = 1; i < 5; i++) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				for (int j = 0; j < 8; j++) {
					magnet[i][j] = Integer.parseInt(st.nextToken());
				}
			}

			// 명령어 입력
			for (int i = 0; i < K; i++) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				int num = Integer.parseInt(st.nextToken()); // num 자석을 d방향으로 회전
				int d = Integer.parseInt(st.nextToken());
				dir[num] = d;
				setDirLeft(num - 1); // num 기준 좌측로 회전방향 세팅
				setDirRight(num + 1); // num 기준 우측으로 회전방향 세팅
				moveMagnet(); // 각 톱니바퀴들을 회전방향에 맞게 회전
			}
			for (int i = 1; i < 5; i++) {
				if (magnet[i][0] == 1)
					res += Math.pow(2, i - 1);
			}
			System.out.println("#" + t + " " + res);
		}
	}

	private static void moveMagnet() {
		for (int i = 1; i < 5; i++) {
			int d = dir[i];
			if (d == 0) // 회전 X이면
				continue;
			else if (d == 1) {
				magnet = Circle(i, magnet); // i번째 톱니바퀴 시계방향 회전
			} else if (d == -1) {
				magnet = ReverseCircle(i, magnet); // i번째 톱니바퀴 반시계방향 회전
			}
		}

	}

	private static int[][] ReverseCircle(int num, int[][] magnet) { // 반시계
		int data[] = copy(magnet[num]);
		for (int i = 0; i < 8; i++) {
			magnet[num][i] = data[(i + 1 + 8) % 8];
		}
		return magnet;

	}

	private static int[][] Circle(int num, int[][] magnet) { // 시계
		int data[] = copy(magnet[num]);
		for (int i = 0; i < 8; i++) {
			magnet[num][i] = data[(i - 1 + 8) % 8];
		}
		return magnet;
	}

	private static int[] copy(int[] arr) { // 배열 복사
		int[] tmp = new int[arr.length];
		for (int i = 0; i < arr.length; i++)
			tmp[i] = arr[i];
		return tmp;
	}

	private static void setDirLeft(int num) {
		if (num == 0)
			return;
		// num의 2번과 num+1의 6번 비교
		if (dir[num + 1] == 0)
			dir[num] = 0;
		else if (magnet[num + 1][6] == magnet[num][2])
			dir[num] = 0;
		else
			dir[num] = dir[num + 1] == -1 ? 1 : -1; // 반대 방향 회전

		setDirLeft(num - 1);
	}

	private static void setDirRight(int num) {
		if (num > 4)
			return;
		// num의 6번과 num-1의 2번 비교
		if (dir[num - 1] == 0) // 이전 자석이 회전 X 이면 자신도 회전 x
			dir[num] = 0;
		else if (magnet[num - 1][2] == magnet[num][6]) { // 자성이 같을 경우 회전 X
			dir[num] = 0;
		} else {
			dir[num] = dir[num - 1] == -1 ? 1 : -1; // 반대 방향 회전
		}
		setDirRight(num + 1);

	}

}

🌟 비슷한 유형의 문제들

[백준 14891] 톱니바퀴 (Gold 5) (자석이 톱니바퀴로만 바뀌었을뿐, 아예 똑같은 문제이다.)


참고

0개의 댓글