🕐 풀이시간 : 약 1시간
엄청 예전에 코테를 한 번 본 적이 있는데 그 때 이런 류의 문제가 나왔다. 당시에 이런 류의 문제를 풀어본 적이 없어서 적잖게 당황해서 총 3문제가 있었는데 해당 문제에 절반의 시간을 사용해버렸다. 어떻게 풀긴 풀었지만 당시에 이렇게 푸는 게 맞는가 하는 의문이 들었다.
아무튼 코테를 쳤을 때 이런 류의 문제를 만난 적이 있는데 제대로 풀었었는지 스스로도 확신이 없었기 때문에 이 문제를 해결해보며 확실히 이런 문제의 해결방법을 다졌다!!
첫 시도
첫 시도에는 예전에 푼 아이디어 그대로 풀어보려고 했다.
1.while(현재 배열의 0인 부분이 있다면 계속)
2.오른쪽,왼쪽,위,아래 중 적절히 판단해서 빈 곳 방향으로 쭉 전진
이런 식으로 해결하려고 했었는데 아무리 생각해도 계속 배열의 모든 공간을 확인하는 부분도 그렇고 원만하게 코드가 안 만들어져서 다른 방법을 찾아봤다.
해결
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를 해서 이동할 방향을 정해줄 수 있겠다라는 생각이 들었다!!
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();
}
}
}