[SWEA][JAVA] Magnetic

Boknami·2023년 10월 26일

SWEA

목록 보기
12/14

💡 IDEA

🔍 첫 생각

큰 2개의 반복문

  • 1,2 발견 => 위 아래 뚫린거면 0으로 변경
  • 남은 것들은 못 나가는거니까 한 열씩 저장 공간에 담아서 교착상태판단

🔍 두번째 생각

위 방법대로 하려다가 문득 애초에 전부 열 배열로 만들어놓고 양극을 while로 제외하면 되겠다라는 생각이 들었다.

  • 맨 아래에 1(N)은 제거 (그냥 바로 S극으로 가면 되니까)
  • 맨 위에 2(S)는 제거 (그냥 바로 N극으로 가면 되니까)

이렇게 하고 구현을 시작했다.

문제는 이제 고착상태를 판단하는건데..
고착상태 판단을 위해서 리스트에서 하나씩 제거하면서 1,2짝이 맞으면 정답++를 해주었다!

그러나...테케중에 맞은 게 없음 ㅠ
고착상태를 제대로 판단 못하는 거 같다..


😥 틀린 코드

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

public class Main
{
    public static void main(String args[]) throws Exception
    {
        Scanner sc = new Scanner(System.in);

        for(int test_case = 1; test_case <= 1; test_case++)
        {
            int answer=0;
            int len = sc.nextInt();;
            int[][] board = new int[len][len];
            for(int i = 0 ; i < len; i++){
                for(int j=0;j<len;j++){
                    board[i][j] = sc.nextInt();
                }
            }

            for(int i = 0 ; i < len; i++){
                List<Integer> magnetics = new ArrayList<>();
                for(int j=0;j<len;j++){
                    //한 열에 1,2 자성체 전부 저장
                    if(board[j][i] == 1 || board[j][i] ==2)
                        magnetics.add(board[j][i]);
                }

                //해당 열에 자성체가 없으면 다음으로!
                if(magnetics.isEmpty())
                    continue;

                //값이 1(N극)인데 아래쪽에 남아있다 => 삭제
                while(!magnetics.isEmpty() && magnetics.get(magnetics.size()-1) == 1){
                    magnetics.remove(magnetics.size()-1);
                }

                //값이 2(S극)인데 위쪽에 남아있다 => 삭제
                while(!magnetics.isEmpty() && magnetics.get(0) == 2){
                    magnetics.remove(0);
                }

                for (int a : magnetics)
                    System.out.print(a + " ");
                System.out.println();

                //남아 있는 녀석들은 교착 상태임
                while(!magnetics.isEmpty()){
                    int cur = magnetics.remove(0);
                    if(cur == 1){
                        if(!magnetics.isEmpty()){
                            int extract = magnetics.remove(0);

                            if(extract == 2)
                                answer++;
                        }
                    }
                    else if (cur == 2) {
                        if(!magnetics.isEmpty()) {
                            int extract = magnetics.remove(0);

                            if (extract == 1)
                                answer++;
                        }
                    }
                }
            }
            System.out.println("#" + test_case + " " + answer);
        }
    }
}

📌 문제 분석

도저히 내가 어디서 틀린 지 모르겠다..
일단 틀린 사고부터 체크해야한다.

기본적으로 빠져나올 수 있는 극들을 빼줄 필요가 없음

이게 무슨 말이냐하면 N극인데 아래가 쭉 비어있는 녀석들이나 S극인데 위가 쭉 비어서 탈출이 가능한 아이들도 굳이 우리가 빼줄 필요가 없다는 의미이다.

왜나하면 우리가 교착상태를 1과2가 만나는 경우에 ++를 해줬으니까 애초에 이 놈들은 교착상태가 될 확률이 없는 녀석들인거다.

이 과정을 제거하고 코드를 돌려도 정답은 아닌..하..뭐가문제냐 ㅠㅠ

리스트에 저장 안해도 돼

자석들이 몇 개가 있을 지 모르니까 List를 이용했는데..
그냥 열을 쭉 돌면서 1이 있으면 flag On하고 2를 만나면 다시 플래그 끄고 ++를 하면 깔끔히 해결.. 너무 복잡하게 문제를 끌고 갔다. 근데 정답도 안나옴 ㅠㅠ


왜 열에서 1이 나온 후 2가 나온 거만 체크해요!!?

풀이를 정상적으로 하신 분들은 열을 체크하면서 1이 나타나면 last=1로 두고 2가 나타나면 last=1인 경우에만 정답++를 한다.

즉 last=2인 상태에서 1이 나타나는 건 추가를 안한다는 의미

1
2
2
1
1

이 경우를 생각해보자
한 번 1,2를 제거한다치면?

2
1
1

여기서 2,1을 묶어서 하나라고 생각했다..
그런데 여기서 다시 확인할 게 2는 위로 가고, 1은 아래로 가는데..
2위가 비었고 1아래가 비었으니까..

1

이렇게 된다! 그렇니까 할 필요가 없지..


💻성공 코두

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

public class Main
{
    public static void main(String args[]) throws Exception
    {
        Scanner sc = new Scanner(System.in);

        for(int test_case = 1; test_case <= 10; test_case++)
        {
            int answer=0;
            int len = sc.nextInt();;
            int[][] board = new int[len][len];
            for(int i = 0 ; i < len; i++){
                for(int j=0;j<len;j++){
                    board[i][j] = sc.nextInt();
                }
            }

            for(int i = 0 ; i < len; i++){
                //열 탐색을 시작
                int flag = 0;
                for(int j=0;j<len;j++) {
                    //1만나면 flag On
                    if(board[j][i] ==1)
                        flag = 1;
                    else if(board[j][i] ==2){
                        if(flag == 1)
                            answer++;
                        flag = 2;
                    }
                    //2만나고 flag On이면 기록
                }
            }
            System.out.println("#" + test_case + " " + answer);
        }
    }
}

0개의 댓글