Seren dev's blog
article thumbnail

https://www.acmicpc.net/problem/10994

 

10994번: 별 찍기 - 19

예제를 보고 규칙을 유추한 뒤에 별을 찍어 보세요.

www.acmicpc.net

풀이

처음 예제 출력을 보면, 1은 별 하나가 찍혀있고, 2는 1의 출력에서 위아래 1줄을 띄고 감싸는 것 같은 모양이다.

 

별이 찍히는 규칙을 살펴보자면, 일단 가운데 줄을 기준으로 위아래가 대칭이다.

홀수 번째 줄의 경우, 맨 윗줄은 모두 별로 채워져 있고, 그 다음 홀수 번째줄부터 계속 양쪽 사이드에서 별이 1개씩 줄어들고 있다.

짝수 번째 줄의 경우, 처음 줄(위에서 2번째)은 양 끝에 별이 1개씩 있고, 그 다음 짝수 번째줄부터 계속 양쪽 사이드에서 별이 1개씩 추가되고 있다.

 

위와 같은 규칙을 코드로 구현하면 아래와 같다.

코드

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));
		int n = Integer.parseInt(br.readLine());
		
		int size = 4*n-3; // 배열의 가로,세로 크기
		char[][] stars = new char[size][size];
		
		// stars 배열을 ' '로 초기화한다.
		for (int i = 0; i < size; i++)
			Arrays.fill(stars[i], ' ');
		
		// 가운데를 기준으로 대칭이므로 배열의 윗부분만 채운다.
		for (int i = 0; i <= size / 2; i++) {
			// 첫번째 줄은 모두 별
			if (i == 0) {
				for (int j = 0; j < size; j++) {
					stars[i][j] = '*';
				}
			}
			// 두번째 줄은 양 끝만 별
			else if (i == 1) {
				stars[i][0] = stars[i][size-1] = '*';
			}
			else {
				// i가 홀수인 경우
				// 현재 줄에서 두 줄 위의 줄을 복사한 다음 별을 2개 추가한다.
				if (i%2 == 1) {
					stars[i] = Arrays.copyOf(stars[i-2], size);
					stars[i][i-1] = stars[i][size-i] = '*';
				}
				// i가 짝수인 경우
				// 현재 줄에서 두 줄 위의 줄을 복사한 다음 별을 2개 뺀다.
				else {
					stars[i] = Arrays.copyOf(stars[i-2], size);
					stars[i][i-1] = stars[i][size-i] = ' ';
				}
			}
		}
		
		// 배열의 아랫부분을 채운다.
		for (int i = size/2 + 1; i < size; i++) {
			stars[i] = Arrays.copyOf(stars[size-1-i], size);
		}
		
		// 정답 출력
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++)
				sb.append(stars[i][j]);
			sb.append("\n");
		}
		System.out.println(sb);
	}
	
}
  • Arrays.fill(stars[i], ' ')
    • 일단 먼저 stars 배열을 ' '로 초기화한다. 이 때 주의할 점은 Arrays.fill() 메서드는 일차원 배열만을 인자로 받기 때문에 이차원 배열의 각 줄을 인자로 넘겨야 한다.

 


다른 풀이 2

재귀함수를 사용하여 바깥쪽부터 안쪽으로 사각형 테두리를 그리듯이 별을 그린다.

BufferedWriter를 사용해 출력한다.

 

로직

1. size는 입력받은 숫자 n의 (4n - 3) 이다.

2. Arrays.fill(stars[i], ' ')로 stars 배열을 ' '로 초기화한다.

3. drawStar(0, size)를 호출한다. 이 때 s는 시작 위치, len는 끝 위치다.

4. len == 1이면 리턴하고, 아니면 drawStar(s+2, len-2)를 호출한다.

5. 재귀함수가 종료하면 BufferedWriter를 사용해 정답을 출력한다.

import java.io.*;
import java.util.*;

public class Main {
	
	static int size;
	static char[][] stars;
	
	public static void drawStar(int s, int len) {
		
		for (int i = s; i < len; i++) {
			stars[s][i] = '*'; // 맨 위 가로줄
			stars[len-1][i] = '*'; // 맨 아래 가로줄
			stars[i][s] = '*'; // 왼쪽 세로줄
			stars[i][len-1] = '*'; // 오른쪽 세로줄
		}
		
		if (len == 1)
			return;
		else
			drawStar(s+2, len-2);
	}
	
	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		int n = Integer.parseInt(br.readLine());
		
		size = 4*n - 3;
		stars = new char[size][size];
		
		for (int i = 0; i < size; i++)
			Arrays.fill(stars[i], ' ');
		
		drawStar(0, size);
		
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++)
				bw.write(stars[i][j]);
			bw.write('\n');
		}
		
		bw.flush();
		bw.close();
		br.close();
	}
	
}

 

참고: https://baelanche.tistory.com/118

 

2번째 방법이 메모리와 실행 시간 측면에서 더 좋은 것을 확인할 수 있다. 또한 재귀함수를 사용하는 방법이 더 직관적이고 가독성이 좋다.

728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!