개발새발 로그

[JS] 백준 2447 : 별 찍기 본문

알고리즘

[JS] 백준 2447 : 별 찍기

이즈흐 2023. 7. 24. 19:27

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

 

2447번: 별 찍기 - 10

재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이

www.acmicpc.net

 

📋풀이방법

1. NxN의 좌표를 모두 순회하면서 별을 찍을 자리가 맞는지 확인한다,

2. 확인하는 방법은 아래와 같다.

 - 1. 만약 x와 y 좌표가 3으로 나눴을 때 나머지가 1이라면 빈칸이다.

 -  if(i % 3 == 1 && j % 3 ==1) 

  ->, (1,1), (1,4) ...이 공백을 출력해야 하는 위치인 것을 알 수 있고,

이 패턴이 반복되기 때문에 i, j의 1 % 3(1 나머지 3)의 값이 1인 곳은 공백으로 처리를 하면 첫번째 단계는 해결이 된다.

 

- 2. 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다.

   -> 이 조건 없이 별을 체크하게 되면 아래와 같이 된다.

가운데 패턴이 들어가지 않은 모습

  ->첫번째 우리가 공백으로 처리한 부분 이외에 추가로 공백으로 처리해야하는 좌표는 아래와 같다.

(3,3) (3,4) (3,5)

(4,3) (4,4) (4,5)

(5,4) (5,4) (5,5)

...

(9,9) (9,10) (9,11)

(10,9) (10,10) (10,11)

(11,9) (11,10) (11,11)

현재 비워져있어야하는 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴의 좌표이다.

 

이 규칙에서 x와 y좌표를 3으로 나눴을 때 몫이 두 좌표 모두 0이 나오지않는다면

재귀를 통해 3으로 나눈 x와y좌표를 다시 호출해준다. 

->이유는 3으로 나눈 좌표를 다시 수행함으로써 if(i % 3 == 1 && j % 3 ==1) 에 걸려져 빈 칸이 출력되기 때문이다.

->여기서 어려운 이유는 왜 3으로 나눈 좌표값을 다시 재귀로 호출했을 때 if문에 걸러지는지다.

 -> 3, 4, 5 이 좌표를 예를 들면 x,y 값이 모두 3^1과 3^1+3^1 사이에 존재한다.

->이 말은 즉  3^1부터 3^1 크기의 정 사각형이 빈 공백으로 표시가 된다.

그래서 3~5까지는 모두 공백(n%3==1일때)으로 출력이 되도록 3으로 나눈 값의 몫만을 취해서 재귀로 호출한다.

 

3. 이를 모든 좌표를 순서대로 순회하면서 배열에 차례로 빈칸인지 별인지 넣어준다.

🤟내 제출

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim();
input=input.replace(/\r/g,"").split("\n");

let N=Number(input.shift());

const lines = []
for(let i = 0; i < N; i++) {
    for(let j = 0; j < N; j++) {
        star(i, j)
    }
    lines.push("\n")
}

function star(i, j) {
    //가운데 비는 곳
    if(i % 3 == 1 && j % 3 == 1) {
    // (1,1), (1,4), (1,7)...
        lines.push(" ")
    } 
    //정해진 가운데 비는 곳이 아니면
    else {
        if(Math.floor(i / 3) === 0 && Math.floor(j / 3) === 0){
            lines.push("*")
        } else {
            // 예를 들어, 9x9 정사각형이라면
            // 3.3 부터 5.5까지는 완전히 빈공간이 되어야한다.
            // 즉 3으로 나누고 재귀함수로진행하면 if(i % 3 == 1 && j % 3 == 1) 이 조건에 걸리게 된다.->무조건 1이 남는다 3~5를 나누면 1.0...
            // (3,3) ~ (3,5), (4,3) ~ (4,5), (5,3) ~ (5,5)
            // 해당 좌표들은 공백
            star(Math.floor(i / 3), Math.floor(j / 3));
        }
    }
}

console.log(lines.join(""))

 

 

어려웠던 점

1. 규칙을 찾기가 어려웟다

 -if(i % 3 == 1 && j % 3 ==1) -> 빈칸이어야하는 좌표

 - if (Math.floor(i/3) ==0 && Math.florr(j/3) == 0) -> 별을 표시해야하는 좌표

-> 이 두가지 규칙을 알아냈어야 했다.

2.  (N/3)×(N/3) 정사각형을 크기 N/3의 패턴의 좌표를 구했어야햇다

 패턴의 좌표에 규칙을 찾아내지 못했다.

(3,3) (3,4) (3,5)

(4,3) (4,4) (4,5)

(5,4) (5,4) (5,5)

3, 4, 5라는 좌표는 빈공간을 출력해야한다

3으로 나누면 모든 좌표가 몫이 1이 나오는 좌표들이다.

728x90
반응형
LIST