본문 바로가기
알고리즘/SWEA

[SWEA / 달팽이 숫자 / JAVA]

by KDW999 2023. 4. 6.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PobmqAPoDFAUq 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

문제 접근

머리론 되게 쉬워보이는데 일일이 구현하는 건 생각보다 시간이 걸렸다.

움직이는 방향을 boolean 타입으로 지정해서 어디로 움직일지 방향을 잡아준다.

달팽이는 2차원 배열 공간을 움직이며 움직이는 공간에 1씩 증가된 값을 저장시켜준다.

달팽이가 다음 경로로 갈 수 없는 경우는 크기를 벗어나게 될 때와 값이 저장되어 있는 경우다. → int형 배열은 초기값을 지정해주지 않으면 default로 0이 들어가있다.

4방향으로 움직이면서 다음 경로로 갈 수 없는 경우의 수를 다 만들어주었다.

해당 방향으로 움직일 때(true)만 갈 수 없는 경우를 탐색하도록 하였음  → 해당 방향 아닌데도 조건을 만족한 다른 방향이 돌아가는 경우가 있었기 때문

 

++ 이제보니 값 저장할 변수로 number를 안쓰고 반복문에서 k를 활용해도 되겠더라

import java.util.*;
import java.io.*;
 
public class Solution {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         
        int T = Integer.parseInt(br.readLine());
         
        for(int t=0; t<T; t++) {
         
            int N = Integer.parseInt(br.readLine());
             
            int[][] snail = new int[N][N];
            int number = 1;
             
            int X = 0;
            int Y = 0;
            snail[Y][X] = number; // 시작
            boolean XPlusMove = true;
            boolean XMinusMove = false;
            boolean YPlusMove = false;
            boolean YMinusMove = false;
             
                for(int k=1; k<N*N; k++) {
                    if(XPlusMove) X++;
                    else if(XMinusMove) X--;
                    else if(YPlusMove) Y++;
                    else if(YMinusMove) Y--;
                     
                    // 이동 방향이 true일 때만 장애물 탐색 작동시키기
                    if(XPlusMove == true) {
                      if(X >= snail[0].length || (X < snail[0].length && snail[Y][X] != 0)) { // 오른쪽 이동 중 크기를 벗어나거나 경로에 값이 있다면
                        X--; // 범위를 벗어나니 다시 감소
                        Y++; // 방향 전환
                        XPlusMove = false;
                        YPlusMove = true;
                      }
                    }
                    if(YPlusMove == true) {
                      if(Y >= snail.length || (Y < snail.length && snail[Y][X] != 0)) { // 아래로 이동 중 크기를 벗어나거나 경로에 값이 없다면
                        Y--; // 범위를 벗어나니 다시 감소 
                        X--; // 방향 전환
                        YPlusMove = false;
                        XMinusMove = true;
                      }
                    }
                    if(XMinusMove == true) {
                      if(X < 0 || (X >= 0 && snail[Y][X] !=0)) { // 왼쪽으로 이동 중 크기를 벗어나거나 경로에 값이 없다면
                        X++; // 범위를 벗어나니 다시 감소 
                        Y--; // 방향 전환
                        XMinusMove = false; 
                        YMinusMove = true; 
                      }
                    }
                     
                    if(YMinusMove == true) {
                      if(YMinusMove && Y < 0 || (Y >=0 && snail[Y][X] !=0)) {// 위쪽으로 이동 중 크기를 벗어나거나 경로에 값이 없다면
                        Y++; // 범위를 벗어나니 다시 감소 
                        X++; // 방향 전환
                        YMinusMove = false; 
                        XPlusMove = true;
                      }
                    }
                    snail[Y][X] = ++number;
                }
                 
                System.out.println("#"+(t+1));
                for(int i=0; i<snail.length; i++) {
                    for(int j=0; j<snail[0].length; j++) {
                        System.out.print(snail[i][j] + " ");
                    }
                    System.out.println();
                }
            }
      }
  }

 

다른 사람 풀이

Arrays.fill() 은 해당 배열을 전부 값으로 저장하는 메서드

1차원 배열 →  Arrays.fill(배열명, 저장할 값)  /  2차원 배열 → Arrays.fill(배열명[인덱스], 저장할 값)

예전에도 이런 문제 풀이를 볼 때 

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

이런 형태를 본 적이 있는데 이게 이런 유형의 문제를 푸는 정형화된 방법인가?

이 분은 지나갔던 경로를 boolean 타입으로, 방향 전환을 한 줄로 처리하였다.

public static void main(String[] args) throws NumberFormatException, IOException {
	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int Tc = Integer.parseInt(br.readLine());
		
		//오,하,좌,상 순서로 방향배열 만들기
		int dx[] = {0,1,0,-1};
		int dy[] = {1,0,-1,0};
		
		for (int tc = 1; tc <= Tc; tc++) {
			int N = Integer.parseInt(br.readLine());
			
			//N*N 크기의 2차원배열 생성
			int arr[][] = new int[N][N];
			boolean visit[][] = new boolean[N][N];
			
			for (int i = 0; i < N; i++) {
				Arrays.fill(visit[i], false);
			}

			//빈 칸을 다 채울때까지 
			int dir = 0;
			int x = 0;
			int y = 0;	
			for (int i = 1 ; i <= N*N; i++) {
				
				//System.out.println(x + "," + y + " : "+ i);
				//정수 입력 , 방향표시
				arr[x][y] = i; // 값 넣기
				visit[x][y] = true; // 지나간 경로 표시
				
				//다음칸 갈수있는지 확인하기
				int nextx = x + dx[dir];
				int nexty = y + dy[dir];
				
				//방향바꾸기 조건 : 1.범위를 넘어갈때  , 2. 다음칸이 채워져있을때  
				if(nextx >=N || nexty >=N || nextx < 0 || nexty < 0 || visit[nextx][nexty] == true ) {
					dir = (dir+1)%4;			//방향전환
				}
				
				//다음칸 지정
				x = x + dx[dir];
				y = y + dy[dir];
				
			}
			
			//출력하기
			System.out.println("#" + tc );
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					System.out.print(arr[i][j] + " ");
				}
				System.out.println();
			}
			
			
		}//Tc
		
	}

댓글