티스토리 뷰
https://www.acmicpc.net/problem/2447
2447번: 별 찍기 - 10
첫째 줄에 N이 주어진다. N은 항상 3의 제곱꼴인 수이다. (3, 9, 27, ...) (N=3k, 1 ≤ k < 8)
www.acmicpc.net
-
어떻게 풀까?

위의 이미지에서 검은색 동그라미를 친부분이 3을 입력했을 때 나오는 그림이다.
9를 입력했을때는 빨간선으로 나눠진 아홉칸 중 비어있는 가운데가 아닌 한칸이 출력된다.
이미지를 보고 대충의 규칙이 있다는 것은 알 수 있지만 코드로는 어떻게 나타낼 수 있을까?
* | * | * |
* | * | |
* | * | * |
항상 위의 표와 같이, 크게 아홉칸으로 나눌 수 있으며 가운데는 비어있다는 것을 사진을 통해 확인했다. 이는 3x3인 배열에서는 [1][1]만 비어있는 것이라고 볼 수있다.
for문 두개를 돌려 가운데는 ' '를 집어 넣는 식으로 표현할 수 있을것이다.
1 2 3 4 5 6 | for ( int i= 0 ;i< 3 ;i++){ for ( int j= 0 ;j< 3 ;j++){ if (i == 1 && j == 1 ) ary[i][j] = ' ' ; else ary[i][j]= '*' ; } } |
위의 식대로만 돌리면 항상 3x3이기 때문에 문제의 9,27...등의 큰수를 받았을 때는 원하는 결과를 출력하지 않을 것이다. 따라서 한칸일 때만 ' '나 '*'를 집어넣을 수 있도록 조건을 추가해야한다.
따로 makeSrarArray라는 함수를 만들어 인덱스와 크기를 넘기기로 한다.
(인덱스 ->> 어떤 인덱스에 별인지 ' '인지를 넣어야하기때문에 매개변수로 넘겨줘야한다.)
(크기 ->> 크기=1일 때만 값을 넣을 수 있도록 크기체크를 위해 항상 넘겨줘야한다.)
또한 크기가 1이기 이전에 크게 구등분으로 나눠있을 때의 가운데 칸인 [1][1]일 경우에는 해당 칸이 전부 ' '이 들어가도록 해야한다. 즉, [1][1]일 경우엔 '*'을 집어넣지 못하도록 함수를 호출하지 말아야한다. 출력배열 ary의 초기값을 ' '로 둔채 '*'인 경우만 함수를 호출해 배열에 값을 넣도록 만들어보자.
for문 두개를 돌릴 때 (구등분으로 나누는 부분) 가운데([1][1])일 경우에는 함수를 호출하지않고 넘긴다.
(왜? 호출을 넘김으로써 해당칸에는 전부 ' '로 초기화된 값이 남겨져있을 것이기 때문이다.)
나머지인 경우에만 함수를 호출하며 크기가 1일경우엔 무조건 *을 넣는다.
이상 아래와 같은 함수를 만들 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public static void makeStarArray( int x, int y, int num){ if (num == 1 ){ ary[x][y] = '*' ; return ; } int value = num/ 3 ; for ( int i= 0 ;i< 3 ;i++){ for ( int j= 0 ;j< 3 ;j++){ if (i == 1 && j == 1 ) ; else makeStarArray(?,?,value); } } } |
makeStarArray의 첫번째와 두번째 매개변수에 들어갈 인덱스는 어떻게 구할 수 있을까?
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
위 함수의 for문 두개가 구등분한 것을 표현한 것이므로 [0][0]은 1번칸, [0][1]는 2번칸... 을 나타낸다.
즉 x+(value*i), y+(value*j)로 해당칸의 가장왼쪽이며 위인 인덱스(size>1) or 해당 인덱스(size=1)를 표현 할 수 있을 것이다.
예를 들어 9x9일경우 [0][0]일땐 makeStarArray(0,0,3)을 호출하며, 호출된 함수 안에서 크기가 1인 makeStarArray함수에 의해 가운데 ary[1][1]을 제외한 1번칸의 나머지 배열에 '*'이 들어간다. 다음으론 구등분한 칸의 [0][1]인 2칸에 대해 동작한다. 이땐 makeStarArray(0,3,3)이 호출되며, 크기가 1인 makeStarArray함수가 여덟번 호출되어에 가운데인 ary[1][4]를 제외한 2번칸의 나머지 여덟개 배열에 '*'이 들어간다.
이런식으로 반복되는 부분을 찾고 규칙을 만들어 문제를 해결할 수 있다.

-
구현 중 만난 문제/해결
자바 char 배열을 초기화 할 때의 값은 자동으로 null이다. 따라서 출력엔 빈값으로 나온것처럼 보여 그냥 제출할 수 있겠지만, 실제로 제출하면 틀린다. 초기값으로 ' '를 입력해주지않으면 안된다.
-
구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import java.util.Arrays; import java.util.Scanner; public class Main { public static char [][] ary; public static void makeStarArray( int x, int y, int num){ if (num == 1 ){ ary[x][y] = '*' ; return ; } int value = num/ 3 ; for ( int i= 0 ;i< 3 ;i++){ for ( int j= 0 ;j< 3 ;j++){ if (i == 1 && j == 1 ); else makeStarArray(x+(value*i), y+(value*j), value); } } } public static void main(String[] args){ Scanner sc = new Scanner(System.in); StringBuilder sb = new StringBuilder(); int size = Integer.parseInt(sc.nextLine()); ary = new char [size][size]; for ( int i= 0 ;i<size;i++){ Arrays.fill(ary[i], ' ' ); } makeStarArray( 0 , 0 ,size); for ( int i= 0 ;i<size;i++){ for ( int j= 0 ;j<size;j++){ sb.append(ary[i][j]); } sb.append( "\n" ); } System.out.println(sb.toString()); } } |
'Algorithm > 백준(baekjoon)' 카테고리의 다른 글
[백준]1015번: 수열 정렬 (0) | 2019.07.05 |
---|---|
[백준]1074번: Z (0) | 2019.07.02 |
[백준]11729번: 하노이 탑 이동 순서 (0) | 2019.06.24 |
[백준]1436번: 영화감독 숌 (0) | 2019.06.19 |
[백준]1107번: 리모컨 (0) | 2019.06.18 |
- Total
- Today
- Yesterday
- 2447
- java
- leetcode 35
- 백준
- elastic ip
- xmlpullparserexceptioin
- leetcode 350
- 도커
- 뒤늦은 1년 후기
- 릿코드
- ngrok
- leetcode 349
- 언제까지할수있을까
- config.xml
- leetcode 278
- Jenkins
- leetcode 204
- 티스토리코드작성
- binarySearch
- gradle빌드
- webhook
- 별찍기-10
- Github
- 1491
- leetcode 69
- binary search
- Docker
- leetcode 167
- Leetcode717
- LeetCode
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |