SWEA 4013 특이한 자석 JAVA

hyeon·2022년 9월 20일
0

알고리즘 연습

목록 보기
16/23

문제

4013 특이한 자석

풀이

1. Deque를 이용한 방법

앞으로도 add,poll 가능하고 뒤로도 가능한 deque의 특성을 가지고 풀었다.
회전할때의 핵심 로직은 왼쪽 자석과 오른쪽 자석이 움직이는지(다른자성을 띄는지) 파악하고 내 자석의 방향이 시계방향이라면 마지막것을 맨앞으로, 그 반대라면 반대로 해주는 것이다.

  • 회전시키는 sol메소드는 재귀적으로 오른쪽과 왼쪽 자석을 회전시키기때문에 left_go right_go라는 매개변수를 통해 다시 내자석을 돌리지않도록 해주어야한다.

  • deque에는 인덱스를 찾는 기능이 없기때문에 toString하여 string으로 바꾸준다음 3번째 날, 7번째 날을 찾아야한다. 주의해야할점은 [1, 0, 1, 0] 이런식으로 괄호와 쉼표 띄움도 한글자로 치기때문에 7번째 19번째 글자를 찾아야한다.


import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Scanner;

public class swea4013 {
    static int  K,ans;
    static int [][]cycle;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan = new Scanner(System.in);
        int T = scan.nextInt();
        for (int o = 1; o <= T; o++) {
            ans=0;
            K=scan.nextInt();      
            cycle=new int[K][2];
            ArrayList<Deque<Integer>> arr=new ArrayList<>();
            for(int i=0;i<4;i++) {
                arr.add(new ArrayDeque<>());
                for(int j=0;j<8;j++) {
                    int tmp=scan.nextInt();
                    arr.get(i).addLast(tmp);
                }
            }
//            for(int i=0;i<4;i++) {
//                System.out.println(arr.get(i));
//            }
//            
            for(int i=0;i<K;i++) {
                cycle[i][0]=scan.nextInt();   //자석번호
                cycle[i][1]=scan.nextInt();   //회전방향 1(시계) -1(반시계)
                sol(arr,cycle[i][0]-1,cycle[i][1],true,true);
                }
//            System.out.println(arr.get(0).toString().charAt(0));
            
            for(int i=0;i<4;i++) {
                int a=arr.get(i).pollFirst();
//                System.out.println(arr.get(i));
//                System.out.println(a);
                if(a==1) {
                    ans+=Math.pow(2, i);
                }
            }
            
            System.out.println("#" + o + " " + ans);
        }
        

        
        
    }
    public static void sol(ArrayList<Deque<Integer>> arr,int num,int cycle,boolean left_go,boolean right_go) {
        //왼쪽 자석의 3번째 날, 오른쪽 자석의 7번째 날
        //왼쪽이 움직여야하는지 체크
        int left=num-1;
        boolean isleft=false;
        if(left>=0) {   //왼쪽 자석이 존재한다면
            if(arr.get(num).toString().charAt(19)!=arr.get(left).toString().charAt(7)) { //회전 해야한다면
                isleft=true;
            }        
        }
        
        //오른쪽이 움직여야하는지 체크
        int right=num+1;
        boolean isright=false;
        if(right<4) {
//            System.out.println("19: "+arr.get(num).toString().charAt(19)+" 7 : " +arr.get(num).toString().charAt(7));

            if((arr.get(num).toString().charAt(7)-'0')!=(arr.get(right).toString().charAt(19)-'0')) {
                isright=true;
            }
        }
        // 내바퀴 움직이기
        if(cycle==1) {  //시계 방향
            int tmp=arr.get(num).pollLast();
            arr.get(num).addFirst(tmp);
        }else {
            int tmp=arr.get(num).pollFirst();
            arr.get(num).addLast(tmp);
        }
        
        if(isleft&&left_go) {
            sol(arr,left,cycle*(-1),true,false);
        }
        if(isright&&right_go) {
            sol(arr,right,cycle*(-1),false,true);
        }
        
    }
        
}

2. 배열을 사용하는 방법

배열을 사용할때에는 옴기려는 원소하나를 빼주고 한칸씩 뒤로 보내는 과정이 필요하다.

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Scanner;

public class swea4013_array {
    static int  K,ans;
    static int [][]cycle,arr;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan = new Scanner(System.in);
        int T = scan.nextInt();
        for (int o = 1; o <= T; o++) {
            ans=0;
            K=scan.nextInt();      
            cycle=new int[K][2];
            arr=new int[4][8];
            
            for(int i=0;i<4;i++) {
                for(int j=0;j<8;j++) {
                    arr[i][j]=scan.nextInt();
                }
            }

            for(int i=0;i<K;i++) {
                cycle[i][0]=scan.nextInt();   //자석번호
                cycle[i][1]=scan.nextInt();   //회전방향 1(시계) -1(반시계)
                sol(cycle[i][0]-1,cycle[i][1],true,true);
                }
//            System.out.println(arr.get(0).toString().charAt(0));
            
            for(int i=0;i<4;i++) {
                int a=arr[i][0];
//                System.out.println(arr.get(i));
//                System.out.println(a);
                if(a==1) {
                    ans+=Math.pow(2, i);
                }
            }
            
            System.out.println("#" + o + " " + ans);
        }
        

        
        
    }
    public static void sol(int num,int cycle,boolean left_go,boolean right_go) {
        //왼쪽 자석의 3번째 날, 오른쪽 자석의 7번째 날
        //왼쪽이 움직여야하는지 체크
        int left=num-1;
        boolean isleft=false;
        if(left>=0) {   //왼쪽 자석이 존재한다면
            if(arr[num][6]!=arr[left][2]) { //회전 해야한다면
                isleft=true;
            }        
        }
        
        //오른쪽이 움직여야하는지 체크
        int right=num+1;
        boolean isright=false;
        if(right<4) {
//            System.out.println("19: "+arr.get(num).toString().charAt(19)+" 7 : " +arr.get(num).toString().charAt(7));

            if((arr[num][2]!=arr[right][6])) {
                isright=true;
            }
        }
        // 내바퀴 움직이기
        if(cycle==1) {  //시계 방향
            int tmp=arr[num][7];        //맨뒤꺼 빼낸후
            for(int i=7;i>=1;i--) {
               arr[num][i]=arr[num][i-1];
            }             //한칸씩 뒤로 보낸다.
            arr[num][0]=tmp;
            //맨앞에 TMP 넣는다.
        }else {
            int tmp=arr[num][0];        //맨앞꺼 빼낸후
            for(int i=1;i<=7;i++) {
               arr[num][i-1]=arr[num][i];
            }             //한칸씩 앞으로 보낸다.
            arr[num][7]=tmp;
            //맨뒤에 TMP 넣는다.
        }
        
        if(isleft&&left_go) {
            sol(left,cycle*(-1),true,false);
        }
        if(isright&&right_go) {
            sol(right,cycle*(-1),false,true);
        }
        
    }
        
}
profile
남기고 싶은 개발자입니다 :>

0개의 댓글