코테문제

[백준] S1913

dekoms 2023. 9. 24. 00:12

Q. https://www.acmicpc.net/problem/1913

 

1913번: 달팽이

N개의 줄에 걸쳐 표를 출력한다. 각 줄에 N개의 자연수를 한 칸씩 띄어서 출력하면 되며, 자릿수를 맞출 필요가 없다. N+1번째 줄에는 입력받은 자연수의 좌표를 나타내는 두 정수를 한 칸 띄어서

www.acmicpc.net

 

# 아이디어

// 위 오른쪽 아래 왼쪽
int[] dx = { -1, 0, 1, 0 };
int[] dy = { 0, 1, 0, -1 };

항상 가운데에서 시작하고 번호가 매겨지는 방향은 순서대로 상, 우, 하, 좌 순이다.

각 방향마다 for문을 checkRound만큼 반복하며 동일한 방향으로 cnt를 채우자!

 

cnt: 표 안의 숫자

checkRound: 동일한 방향으로 몇 번 for문을 반복하며 cnt를 채울지 제어함.

direction: 0, 1, 2, 3 순으로 상, 우, 하, 좌임.

cnt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
checkRound &1 1 &2 2 &2 2 &3 3 3 &3 3 3 &4 4 4 4
direction 0 1 2 3 4 4 0 0 0 1 1 1 2 2 2 2

=> 표의 각 모서리 느낌? 나는 곳마다 checkRound를 증가시킨다. 하지만 &가 붙은 경우에는 다음 checkRound도 동일하기에 checkRound를 유지해줘야 한다!!!

 

#오답

- 런타임에러 발생..

- 3x3을 넘어가면 오류발생

Sol1.

checkRound 증가하는 규칙 확인해보자..?

checkRound 점화식: 어떻게 써야할지 모르겠다!!!

 

Sol2.

checkRound 점화식은 모르지만 isStay를 사용하여 &가 있는 checkRound인지 아닌지를 구별했다!

내가 너무 어렵게 생각한건가... 다음부터는 flag를 적극 활용해보자!!! 😎 😎 😎

- 근데 채점하는데 시간이 드럽게 오래걸림.. BufferedReader로 바꿔보자!

package baekjoon;

import java.util.Scanner;

public class S1913 {

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

		int n = sc.nextInt();
		int findNum = sc.nextInt();

		int[][] box = new int[n][n];
		// 위 오른쪽 아래 왼쪽
		int[] dx = { -1, 0, 1, 0 };
		int[] dy = { 0, 1, 0, -1 };

		int currentX = n / 2;
		int currentY = n / 2;

		int cnt = 1;
		int checkRound = 1;
		int direction = 0;
		boolean isStay = true;
		for (; cnt <= n * n;) {

			direction %= 4;

			switch (direction) {
			case 0:
				for (int i = 0; i < checkRound; i++) {
					box[currentX][currentY] = cnt;
					currentX += dx[0];
					currentY += dy[0];
					cnt++;
				}
				break;
			case 1:
				for (int i = 0; i < checkRound; i++) {
					box[currentX][currentY] = cnt;
					currentX += dx[1];
					currentY += dy[1];
					cnt++;
				}
				break;
			case 2:
				for (int i = 0; i < checkRound; i++) {
					box[currentX][currentY] = cnt;
					currentX += dx[2];
					currentY += dy[2];
					cnt++;
				}
				break;
			case 3:
				for (int i = 0; i < checkRound; i++) {
					box[currentX][currentY] = cnt;
					currentX += dx[3];
					currentY += dy[3];
					cnt++;
				}
				break;
			}
			direction++;

			if (isStay) {
				isStay = false;
				continue;
			}

			checkRound++;
			isStay = true;

		}

		StringBuilder stringBuilder = new StringBuilder();

		int resX = -1;
		int resY = -1;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (findNum == box[i][j]) {
					resX = i + 1;
					resY = j + 1;
				}
				stringBuilder.append(box[i][j] + " ");
			}
			stringBuilder.append("\n");
		}
		stringBuilder.append(resX + " " + resY);
		System.out.println(stringBuilder.toString());

		sc.close();

	}

}

 

Sol3.

바꾸니까 런타임 에러 났다! ^ㅡ^

그냥 자연수 2개 정도 입력받는 경우는 Scanner 쓰자~~

 

💯💯💯

StringBuilder를 사용하면 한 번에 출력이 가능하다!