Algorithm/Baekjoon(Node.js)

[JavaSrcipt] Baekjoon - 2292 : 벌집 (for,while)

비망노트 2021. 9. 20. 23:24

문제

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.

입력

첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.

출력

입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.

 

예제입력 예제출력
13 3

 

❌ 풀이

배열[0]은 1이고 방의갯수는 1개    즉 숫자0부터1까지
[1]은[0]+6까지이고 방의갯수는 6개증가 즉 숫자2부터7까지
[2]는 [1]+6까지이고 방의갯수는 12개증가 즉 8부터19까지 
[3]은 [2]+6까지이고 방의갯수는 18개증가 즉 20부터37까지 
[4]는 [3]+6까지이고 방의갯수는 24개증가 즉 38부터61까지   

즉 각 벌집의 방갯수가 6의 배수만큼 증가하고있다.

 

이런식으로 각 인덱스에 1,7,19,37,61 --- 을 넣으며 해당 인덱스의 값이 입력값보다

크다면 빠져나오고 해당 인덱스 +1을 출력하는 방식으로 하려고생각했었다.

하지만 6 12 18 --- 을

for(let o=;;o++){
	for(let i=1;i<input;){
          [o]=[o-1]+i   
    	  i+=6;     
	}
}

이렇게해보니 일단 [o-1] 즉 [-1] 인덱스가 undefined라서

NaN이 배열에 들어가서 안됐고,

다른방법으로는 

자꾸 공식자체를 잘못세운것같이 input값 만큼 증가되고

아니면 6의배수+1 7 13 19 --- 다들어가서..

 

결국 이번에도 구글링..

 

 

✅ 다른분의 풀이

const input = require('fs').readFileSync('/dev/stdin');

let range = 1, block = 1;

while (block < input) {    
	block += 6 * range;

	range++;
}

console.log(range);

range를 이동하는데 지나가는 방갯수라고 가정하고

block을 총 방의갯수 라고 가정하여

 

방의갯수가 입력값보다 작을때까지만 

block += 6 * range를 하며

range++; 을 하였는데

이 공식을 생각을 하지못했다.

이게 필요했던건데..

 

1 += 6 해서 첫반복때는 block이 7이되었고

다음번엔 range값이 2가되었으므로

7 + 6*2 즉 12를 더할 수 있다.

 

input값이 1이라면 조건에 부합하지않으므로 range++를하지못해 첫값 1이 출력

 

이렇게 반복하다 예를들어 입력값이 80이라면

1 7 19 37 61 block이 61일때 range는 5고 80보다 작으므로

한바퀴 더 실행. 즉 block이 91이되고 range를 증가시켰을때 조건끝 즉 range=6

 

 

const input=require('fs').readFileSync('/dev/stdin');
let room=1;
for(var i=1;room<input;i++){
    
    room += 6 *i;
}console.log(i)

참고하여 for문을 사용해 풀어봤는데

for문에 i를 전역변수 var로해주고

조건을 i에 주는게아닌 외부변수 room에 주다보니 

뭔가 지저분해보인다.

 

✅ for, while 

for(초기값; 조건식; 증감연산) {
  실행문;
}

while (조건식) { 
  실행문;
}
< for문으로 구현 >

for (int i=0; i<10; i++) {
  System.out.println("1");
}

< while문으로 구현 >

int i=0;

while (i<10) {
  System.out.println("1");
  i++;
}


❗ while문의 초기값과 증감연산의 위치주의

for문과 while문은 서로 바꾸어 쓸 수 있지만 사용용도에따라 다르게 쓰인다.

 

❗ for문

반복횟수가 정해진경우,

주로 배열과 함께 쓰임.

 

무한루프

for(;;){

}

 

 while문

무한루프나 특정조건에 만족할때까지 반복해야하는경우.

- 루프의 실행을 어느 시점에서 종료해야하는 경우 조건문과 break로 종료
- 루프 실행을 계속해야하는 경우 continue 문사용

 

무한루프

while(1){

}

 

 

 

이전 단원들은 해당 풀이에 맞는 메소드를 아는지모르는지가 코드간결화에 영향을 미쳤다면

기본수학에서는 말그대로 수학적 사고를 할 수 있는지 없는지가 중요한것같다.

그래서그런가 다른분의 풀이를 볼때마다 와.. 이렇게 간단하게 표현할 수 있구나 싶다.

 

 

-출처

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