728x90
반응형
2024.09.12기준 - 실버3
728x90
백준, BEAKJOON, BOJ, JAVA, 자바
풀이
이 문제는 해당하는 규칙에 맞게 달팽이 모양을 채워주고 입력받은 숫자의 좌표를 출력하는 문제입니다.
1. 우선 풀이에 필요한 변수들을 저장했습니다.
int[][] grid = new int[n][n]; // 수를 저장할 배열
boolean[][] visit = new boolean[n][n]; // 수를 저장했는지 체크하는 배열
int num = n * n; // 0,0에서 시작하는 번호
int cen = n / 2; //
int[] dx = {0, 1, 0, -1}; // 이동할 x좌표
int[] dy = {1, 0, -1, 0}; // 이동할 y좌표
int dir = 0; // 남, 동, 북, 서
// 현재 좌표와 다음으로 갈 좌표
int nowy = 0, nowx = 0, nextx, nexty;
- 저의 접근은 달팽이 모양을 만들 때, 가장 큰 수 부터 처리하는 방식으로 접근했습니다.
- 가장 가운데 좌표에 도달하면 멈춰야 되기 때문에 cen 변수를 생성해주었습니다.
- dir은 dx와 dy가 움직일 방향에 대한 인덱스로 사용됩니다.
2. 시작 부분을 먼저 체크를 해주었습니다.
(반복문은 다음 좌표부터 체크하기 때문에 우선적으로 작업을 해줍니다.)
// 시작 부분 먼저 체크
visit[nowy][nowx] = true;
grid[nowy][nowx] = num;
3. 참조하는 좌표가 가운데에 도착하면 종료되는 반복문을 생성합니다.
// 참조하는 좌표가 가운데에 도착한다면 반복문 종료
while (!(nowy == cen && nowx == cen)) {
// 만약 표의 범위를 벗어나거나 이미 체크한 곳이라면 방향을 전환해준다.
if (!check(nowy + dy[dir], nowx + dx[dir], n) || visit[nowy + dy[dir]][nowx + dx[dir]]) {
dir++;
if (dir == 4) {
dir = 0;
}
}
// 이동한 좌표
nexty = nowy + dy[dir];
nextx = nowx + dx[dir];
// 이동한 좌표에 입력할 번호
num--;
// 이동한 좌표 체크
visit[nexty][nextx] = true;
grid[nexty][nextx] = num;
// 현재 좌표를 이동한 좌표로 이동
nowy = nexty;
nowx = nextx;
}
- 만약 다음에 참조할 위치가 표를 벗어나거나 이미 체크한 곳이라면 이동할 방향을 바꿔줍니다.
- 이동한 좌표에 숫자를 넣어주면서 체크를 해줍니다.
- 이동한 좌표를 현재 좌표로 업데이트 해줍니다.
4. 완성된 표를 출력하면서 입력받은 위치의 좌표를 저장해주고 출력해줍니다.
// 입력한 번호들을 출력
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sb.append(grid[i][j]).append(" ");
// 찾는 번호는 따로 저장
if (grid[i][j] == m) {
nowy = i;
nowx = j;
}
}
sb.append("\n");
}
// 찾는 번호의 위치 출력
sb.append(nowy + 1).append(" ").append(nowx + 1);
문제에서는 시작좌표는 1, 1이기 때문에 +1을 해주었습니다.
코드
package Main;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(br.readLine()); // 한 변의 길이
int m = Integer.parseInt(br.readLine()); // 찾을 수
int[][] grid = new int[n][n]; // 수를 저장할 배열
boolean[][] visit = new boolean[n][n]; // 수를 저장했는지 체크하는 배열
int num = n * n; // 0,0에서 시작하는 번호
int cen = n / 2; //
int[] dx = {0, 1, 0, -1}; // 이동할 x좌표
int[] dy = {1, 0, -1, 0}; // 이동할 y좌표
int dir = 0; // 남, 동, 북, 서
// 현재 좌표와 다음으로 갈 좌표
int nowy = 0, nowx = 0, nextx, nexty;
// 시작 부분 먼저 체크
visit[nowy][nowx] = true;
grid[nowy][nowx] = num;
// 참조하는 좌표가 가운데에 도착한다면 반복문 종료
while (!(nowy == cen && nowx == cen)) {
// 만약 표의 범위를 벗어나거나 이미 체크한 곳이라면 방향을 전환해준다.
if (!check(nowy + dy[dir], nowx + dx[dir], n) || visit[nowy + dy[dir]][nowx + dx[dir]]) {
dir++;
if (dir == 4) {
dir = 0;
}
}
// 이동한 좌표
nexty = nowy + dy[dir];
nextx = nowx + dx[dir];
// 이동한 좌표에 입력할 번호
num--;
// 이동한 좌표 체크
visit[nexty][nextx] = true;
grid[nexty][nextx] = num;
// 현재 좌표를 이동한 좌표로 이동
nowy = nexty;
nowx = nextx;
}
// 입력한 번호들을 출력
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sb.append(grid[i][j]).append(" ");
// 찾는 번호는 따로 저장
if (grid[i][j] == m) {
nowy = i;
nowx = j;
}
}
sb.append("\n");
}
// 찾는 번호의 위치 출력
sb.append(nowy + 1).append(" ").append(nowx + 1);
bw.write(sb.toString());
bw.flush();
bw.close();
br.close();
}
// 현재 참조하는 좌표가 범위안에 들어가는지 체크하는 함수.
private static boolean check(int y, int x, int n) {
return 0 <= x && 0 <= y && x < n && y < n;
}
}
728x90
반응형
'코딩테스트 일기 (BAEKJOON)' 카테고리의 다른 글
BEAKJOON / 백준 - JAVA 10703번 유성 (1) | 2024.09.14 |
---|---|
BEAKJOON / 백준 - JAVA 25594번 HG 음성기호 (9) | 2024.09.13 |
BEAKJOON / 백준 - JAVA 27952번 보디빌딩 (0) | 2024.09.11 |
BEAKJOON / 백준 - JAVA 25593번 근무 지옥에 빠진 푸앙이 (Small) (0) | 2024.09.10 |
BEAKJOON / 백준 - JAVA 23885번 비숍 투어 (0) | 2024.09.09 |