일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 리액트댓글기능
- 백준js
- 자바스크립트
- JS프로그래머스
- HTML5
- 백준골드
- css기초
- 코테
- 프로그래머스코테
- 포이마웹
- 몽고DB
- dp알고리즘
- 리액트커뮤니티
- 프로그래머스
- 알고리즘
- 백준알고리즘
- 백준구현문제
- js코테
- CSS
- 안드로이드 스튜디오
- 백준
- 익스프레스
- 코딩테스트
- 백준구현
- 다이나믹프로그래밍
- HTML
- 프로그래머스JS
- 백준nodejs
- JS
- 리액트
- Today
- Total
개발새발 로그
[JS] 백준 1011번 : Fly me to the Alpha Centauri - 수학 본문
https://www.acmicpc.net/problem/1011
1011번: Fly me to the Alpha Centauri
우현이는 어린 시절, 지구 외의 다른 행성에서도 인류들이 살아갈 수 있는 미래가 오리라 믿었다. 그리고 그가 지구라는 세상에 발을 내려 놓은 지 23년이 지난 지금, 세계 최연소 ASNA 우주 비행
www.acmicpc.net
수학 알고리즘으로 규칙을 찾아야한다.
💬문제 이해
-아래 그림과 같이 처음과 끝은 1이어야한다.
👁🗨규칙 찾기
거리 (y-x) | 내용 | 가동 횟수 |
1 | 1 | 1 |
2 | 1 1 | 2 |
3 | 1 1 1 | 3 |
4 | 1 2 1 | 3 |
5 | 1 2 1 1 | 4 |
6 | 1 2 2 1 | 4 |
7 | 1 2 2 1 1 | 5 |
8 | 1 2 2 2 1 | 5 |
9 | 1 2 3 2 1 | 5 |
10 | 1 2 3 2 1 1 | 6 |
11 | 1 2 3 2 2 1 | 6 |
12 | 1 2 3 3 2 1 | 6 |
13 | 1 2 3 3 2 1 1 | 7 |
14 | 1 2 3 3 2 2 1 | 7 |
15 | 1 2 3 3 3 2 1 | 7 |
16 | 1 2 3 4 3 2 1 | 7 |
이렇게 나열 후 규칙을 찾아본다
첫 번째 규칙
- 거리 1, 4, 9 .. 값을 기준으로 그 다음 거리의 가동횟수가 1 증가한다.
->1, 4, 9.. 는 제곱수이다.
두 번째 규칙
-현재 제곱수와 다음 제곱수의 사이에서 가동횟수가 1회 증가된다.
->거리 1에서 4 사이에서 가동횟수가 두 번 변한다. 1 -> 2 -> 3
->거리 9에서 16 사이에서 가동횟수가 역시 두 번 변한다.
이 때 변하는 구간인 12는 16 - 4 => 즉 16 - √16 이다.
세 번째 규칙
-첫번째 규칙에서 구한 제곱수 규칙에서 해당 제곱수의 가동횟수는 2 x √n -1 이다.
거리 | 내용 | 가동 횟수 |
1 | 1 | 1 |
4 | 1 2 1 | 3 |
9 | 1 2 3 2 1 | 5 |
16 | 1 2 3 4 3 2 1 | 7 |
1은 2 x √1 -1 = 2
4는 2 x √4 - 1 = 3
...
이런식의 규칙이 생긴다.
☝만약 거리가 제곱수가 아닐 경우에는 가동횟수를 어떻게 구할까?
두번째 규칙을 보면 제곱수 사이에서 가동횟수가 무조건 한번 바뀌게 된다.
그러면 우리는 이를 통해 구해야할 값이 생긴다
1. 거리 k 보다 크면서 가장 가까운 제곱 수
2. 거리 k가 속한 제곱 수 구간의 중간 값 ( 가동횟수가 변하는 구간 )
✅거리 k 보다 크면서 가장 가까운 제곱 수 구하는 방법
->k에 제곱근 연산을 수행하고 이를 반올림한다 (7의 경우 2.646... => 3)
-즉 7보다 크면서 가장 가까운 제곱 수의 제곱 근이 3인 것이다.
-3을 다시 제곱하면 9가 나온다.
-결과적으로 7보다 크면서 가장 가까운 제곱 수는 9가 된다.
✅거리 k가 속한 제곱 수 구간의 중간 값 ( 가동횟수가 변하는 구간 )
-> 변하는 구간 num은 k - √k 이다.
-즉 16의 중간 값은 12다.
-12보다 큰 값이면 16의 가동횟수와 동일하다.
-12 보다 작은 값이면 16의 가동횟수에서 -1한 값이다.
이 규칙을 토대로 아래 코드를 작성했다
🤟내 제출
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 T=Number(input.shift());
let arr=[];
for(var i=0;i<T;i++){
arr.push(input.shift().split(" ").map(Number));
}
let result=[];
arr.forEach((tt)=>{
let [x,y]=tt;
let num=y-x;
let ref=Math.sqrt(num);
if(ref%1==0){
result.push(parseInt(2*ref-1));
}
else{
let next=Math.ceil(ref);
if(num>Math.pow(next,2)-next){
result.push(parseInt(2*next-1));
}
else{
result.push(parseInt(2*next-2));
}
}
})
console.log(result.join("\n"));
💢어려웠던 점
1. 처음에 DP문제인 줄 알았지만 수학문제였다.
-문제를 보고 알고리즘 종류가 무엇인지 잘 파악하자.
2. 문제에서 1광년으로 시작하고 1광년으로 끝나야하는 것이 무엇을 의미하는지 생각하지 못했다.
-수학문제는 규칙을 찾는 것이므로 이러한 조건들이 중요하다.