백준에서 14891번 톱니바퀴 문제와 유사한 문제다. 완전한 구현, 시뮬레이션 문제다.
자석은 총 4개로 지정이 되어있고, 회전시킬때마다 배열이 조정되므로 ArrayList에 각 자석의 값을 담아주었다.
그 후 각 자석마다 움직일 수 있는지 움직일 수 없는지 여부를 판별하기 위해 boolean형태의 크기가 4인 flag배열을 선언해줘서 true일 때만 회전시키도록 구현했다.
입력받은 톱니바퀴 번호를 인자로받아서 check()메소드로 회전시켜야할 자석을 확인하고, 그 자석 번호에 맞는 방향으로 move1(), move2()메소드를 이용해 회전시켜준다. move1()은 시계방향으로 회전, move2()메소드는 반시계방향으로 회전시켜주는 메소드다.
선택된 자석 양쪽은 현재 방향과 반대로 돌기 때문에 1이 시계방향, -1이 반시계방향이라고 한다면 (1, -1, 1, -1), (-1, 1, -1, 1)형태로 돌릴 수 있기에 (첫번째 자석, 세번째 자석)이 같은 방향으로 돌고, (두번째 자석, 네번째 자석)이 같은 방향으로 돈다.
그리고 move1()은 시계방향으로 회전시키므로, 자석 맨 뒤에 값을 빼내어 맨 앞으로 추가하고, move2()은 반시계방향으로 회전시키므로 자석 맨 앞에 값을 빼내에 맨 뒤로 추가한다.
그 후, calc()메소드로 자석 맨 처음 값을 토대로 원하는 답을 출력해준다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Solution {
static ArrayList<Integer>[] magnet;
static boolean[] flag;
static int answer;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
for(int tc=1; tc<=T; tc++) {
magnet = new ArrayList[4];
for(int i=0; i<4; i++) {
magnet[i] = new ArrayList<Integer>();
}
int K = Integer.parseInt(br.readLine());
for(int i=0; i<4; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<8; j++) {
magnet[i].add(Integer.parseInt(st.nextToken()));
} //자석 입력 완료
}
for(int i=0; i<K; i++) {
st = new StringTokenizer(br.readLine());
int magnet_select = Integer.parseInt(st.nextToken()) - 1; //어떤 자석을 움직일건지 선택
int dir = Integer.parseInt(st.nextToken()); //어느 방향으로 돌릴건지 방향 선택
flag = new boolean[4];
flag[magnet_select] = true;
check(magnet_select); //돌려야할 자석 체크
//System.out.println(Arrays.toString(flag));
if(dir == 1) { //선택된 톱니바퀴가 시계방향으로 돌아갈 때
if(magnet_select == 0 || magnet_select == 2) {
if(flag[0]) move1(0);
if(flag[1]) move2(1);
if(flag[2]) move1(2);
if(flag[3]) move2(3);
}
else {
if(flag[0]) move2(0);
if(flag[1]) move1(1);
if(flag[2]) move2(2);
if(flag[3]) move1(3);
}
}
else {
if(magnet_select == 0 || magnet_select == 2) {
if(flag[0]) move2(0);
if(flag[1]) move1(1);
if(flag[2]) move2(2);
if(flag[3]) move1(3);
}
else {
if(flag[0]) move1(0);
if(flag[1]) move2(1);
if(flag[2]) move1(2);
if(flag[3]) move2(3);
}
}
}
answer = calc();
System.out.println("#"+tc+" "+answer);
}
}
private static int calc() {
int sum = 0;
int num = 1;
for(int i=0; i<4; i++) {
sum += (magnet[i].get(0))*num;
num *= 2;
}
return sum;
}
private static void check(int m) {
//첫번째 톱니바퀴가 선택되었을 때
if(m == 0) {
if (magnet[m].get(2) != magnet[m+1].get(6)) {
flag[m+1] = true;
if(magnet[m+1].get(2) != magnet[m+2].get(6)) {
flag[m+2] = true;
if(magnet[m+2].get(2) != magnet[m+3].get(6)) {
flag[m+3] = true;
}
}
}
}
else if(m == 1) {
if(magnet[m].get(6) != magnet[m-1].get(2)) {
flag[m-1] = true;
}
if(magnet[m].get(2) != magnet[m+1].get(6)) {
flag[m+1] = true;
if(magnet[m+1].get(2) != magnet[m+2].get(6)) {
flag[m+2] = true;
}
}
}
else if(m == 2) {
if(magnet[m].get(2) != magnet[m+1].get(6)) {
flag[m+1] = true;
}
if(magnet[m].get(6) != magnet[m-1].get(2)) {
flag[m-1] = true;
if(magnet[m-1].get(6) != magnet[m-2].get(2)) {
flag[m-2] = true;
}
}
}
else {
if (magnet[m].get(6) != magnet[m-1].get(2)) {
flag[m-1] = true;
if(magnet[m-1].get(6) != magnet[m-2].get(2)) {
flag[m-2] = true;
if(magnet[m-2].get(6) != magnet[m-3].get(2)) {
flag[m-3] = true;
}
}
}
}
}
private static void move1(int m) { //시계방향으로 움직이기
int tmp = magnet[m].remove(7);
magnet[m].add(0, tmp);
}
private static void move2(int m) { //반시계방향으로 움직이기
int tmp = magnet[m].remove(0);
magnet[m].add(tmp);
}
}