[SWEA-D2][달팽이 숫자][JAVA]

Boknami·2023년 10월 16일

SWEA

목록 보기
5/14

🕐 풀이시간 : 약 1시간

📋 기록의 이유

엄청 예전에 코테를 한 번 본 적이 있는데 그 때 이런 류의 문제가 나왔다. 당시에 이런 류의 문제를 풀어본 적이 없어서 적잖게 당황해서 총 3문제가 있었는데 해당 문제에 절반의 시간을 사용해버렸다. 어떻게 풀긴 풀었지만 당시에 이렇게 푸는 게 맞는가 하는 의문이 들었다.

아무튼 코테를 쳤을 때 이런 류의 문제를 만난 적이 있는데 제대로 풀었었는지 스스로도 확신이 없었기 때문에 이 문제를 해결해보며 확실히 이런 문제의 해결방법을 다졌다!!


🔎 아이디어

첫 시도

첫 시도에는 예전에 푼 아이디어 그대로 풀어보려고 했다.
1.while(현재 배열의 0인 부분이 있다면 계속)
2.오른쪽,왼쪽,위,아래 중 적절히 판단해서 빈 곳 방향으로 쭉 전진

이런 식으로 해결하려고 했었는데 아무리 생각해도 계속 배열의 모든 공간을 확인하는 부분도 그렇고 원만하게 코드가 안 만들어져서 다른 방법을 찾아봤다.

해결

(1) 어떻게 움직일까?

BFS,DFS 같은 문제를 풀 경우에 dx,dy를 배열에 저장해놓고 4방향으로 이동하는 형식이 있는데 그걸 응용한다!

int[] dx = {0,1,0,-1};
int[] dy = {1,0,-1,0};

while(){
	repeat++;
    if(repeat >= 4) repeat = repeat %4;

현재 달팽이 문제가 돌아가는 방향을 유심하게 봤다. 방향은 항상 일정했고, 그 방향은 <우,하,좌,상> 이 반복되고 있었다. 그렇다면 반복되는 횟수를 기록하고 %4를 해서 이동할 방향을 정해줄 수 있겠다라는 생각이 들었다!!

(2) 조건 세우기

while(true){
	   //배열 인덱스를 넘으면 안돼!
       if(curLoc[0] + dx[repeat] >= N ||
       curLoc[0] + dx[repeat] < 0 ||
       curLoc[1] + dy[repeat] >= N ||
       curLoc[1] + dy[repeat] < 0)
                        break;
       //이미 채워졌다면 멈추자!
       if(board[curLoc[0] + dx[repeat]][curLoc[1] + dy[repeat]] != 0)
                        break;

방향을 정했다면 배열을 초과하거나 이미 채워진 것은 피해가야한다!
해당 경우 조건을 작성했는데 생각보다 너무 길게 되었지만..잘 돌아간다!


💬 문제 회고

이번 기회에 확실히 깨달았다. 나는 구현 문제에 많이 약한 모습을 보인다. 배열에 인덱스를 복잡하게 다루거나 하면 머리가 잘 안 돌아가고 회로가 멈추는 느낌을 받는다..그리고 돌릴때마다 배열의 인덱스를 넘어버리는 경우도 심심치 않다. 구현 문제를 많이 풀어봐야지! 그리고 집중!!!집중하자


💻 코드

import java.util.Scanner;
import java.io.FileInputStream;

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

		for(int test_case = 1; test_case <= T; test_case++)
		{
            System.out.print("#" + test_case + "\n");
			int N = sc.nextInt();
            int[][] board = new int[N][N];
            int curNum = 0;
            int repeat = -1;
            int[] curLoc = {0,-1};
            int[] dx = {0,1,0,-1};
            int[] dy = {1,0,-1,0};
            
            //4x4면 16이 끝이다! 숫자가 끝까지 다 차면 종료!
            while(curNum != N*N){
                //printBoard(board, N);
                //우측, 아래, 왼쪽, 위의 반복!
                //방향을 정하자!
                repeat++;
                if(repeat >= 4) repeat = repeat %4;
                
                //배열의 끝이나 이미 값이 있는 공간까지 이동!
                while(true){
                    if(curLoc[0] + dx[repeat] >= N || curLoc[0] + dx[repeat] < 0 || curLoc[1] + dy[repeat] >= N || curLoc[1] + dy[repeat] < 0)
                        break;
                    if(board[curLoc[0] + dx[repeat]][curLoc[1] + dy[repeat]] != 0)
                        break;
                    
                    curNum++;
                    curLoc[0] += dx[repeat];
                    curLoc[1] += dy[repeat];
                    
                    board[curLoc[0]][curLoc[1]] = curNum;
                }
            }
            printBoard(board, N);
		}
	}
    
    public static void printBoard(int[][] board, int N) {
         for(int i = 0; i < N; i++){
                for(int j = 0 ; j < N; j++){
                    System.out.print(board[i][j] + " ");
                }
                System.out.println();
            }
    }
}

0개의 댓글