1. 문제 요약
정해진 규칙에 따라서 그려지는 소용돌이가 있고 그 중에서 필요한 부분만을 찾아 출력하는 문제이다
2. 입/출력
문제 제한범위가 조금 특이하다.
r1,c1,r2,c2가 가질 수 있는 값은 넓지만
r2-r1, c2-c1이 가질 수 있는 값은 작다.
3.
만약 값들이 가질 수 있는 값의 최대범위에 맞춰서 배열 사이즈를 정하면 메모리 초과가 발생한다. 따라서 딱 필요한 만큼만 저장하는 것이 필요하다.
그래서 생각한 풀이 방법은 정해진범위까지 숫자를 탐색하는데 기록할 위치만 기록하자 이다.
중앙부에서부터 수를 늘리면서 범위안에 있으면 배열에 쓰고 아니면 말기!
4. 구현 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int[][] map;
static int[][] dir = { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int r1 = Integer.parseInt(st.nextToken());
int c1 = Integer.parseInt(st.nextToken());
int r2 = Integer.parseInt(st.nextToken());
int c2 = Integer.parseInt(st.nextToken());
// 결과를 담을 배열
int h = r2 - r1 + 1;
int w = c2 - c1 + 1;
map = new int[h][w];
// 배열에 값 채우기
int x = 0, y = 0, d = 0, num = 1, cnt = 0, wCnt = 0, dCnt = 1;
while (true) {
// 배열을 타 채우면 벗어남
if(wCnt >= h*w) {
break;
}
if (x >= r1 && x <= r2 && y >= c1 && y <= c2) {
map[x - r1][y - c1] = num;
wCnt++;
}
num++;
cnt++;
x = x + dir[d][0];
y = y + dir[d][1];
if (cnt == dCnt) {
cnt = 0;
// 좌나 우로 값을 채울때 칸이 하나씩 늘어남
if (d == 1 || d == 3)
dCnt++;
d = (d + 1) % 4;
}
}
// 예쁘게 출력시키기
int blank = (int)(Math.log10(num)+1);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int len = (int)(Math.log10(map[i][j])+1);
for (int k = 0; k < blank-len; k++) {
System.out.print(" ");
}
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
}